Unverified Commit 823bc5ba by Miodrag Milanović Committed by GitHub

Merge pull request #24 from YosysHQ/xc7srl

Supporting tests for Xilinx SRLs -- YosysHQ/yosys#914
parents 61f5ba72 3f4c2bbe
......@@ -8,6 +8,10 @@ else
export YOSYS_NOVERIFIC=1
endif
ifeq ($(ENABLE_HEAVY_TESTS),1)
export ENABLE_HEAVY_TESTS=1
endif
all: $(addsuffix /.stamp,$(SUBDIRS))
echo; find * -name "*.status" | sort | xargs grep -H . | sed 's,^, ,; s,.status:,\t,; s,PASS,pass,;' | expand -t100; echo
touch .stamp
......
......@@ -69,6 +69,9 @@ $(eval $(call template,synth_sf2_error,synth_sf2_fully_selected ))
#xilinx
$(eval $(call template,synth_xilinx,synth_xilinx synth_xilinx_top synth_xilinx_blif synth_xilinx_edif synth_xilinx_run synth_xilinx_flatten synth_xilinx_retime synth_xilinx_vpr synth_xilinx_arch_xcup synth_xilinx_arch_xcu synth_xilinx_arch_xc7 synth_xilinx_arch_xc6s synth_xilinx_nobram synth_xilinx_nodram synth_xilinx_nosrl))
$(eval $(call template,synth_xilinx_error,synth_xilinx_fully_selected synth_xilinx_invalid_arch ))
ifeq ($(ENABLE_HEAVY_TESTS),1)
$(eval $(call template,synth_xilinx_srl,synth_xilinx_srl))
endif
#greenpak4
$(eval $(call template,synth_greenpak4,synth_greenpak4 synth_greenpak4_top synth_greenpak4_json synth_greenpak4_run synth_greenpak4_noflatten synth_greenpak4_retime synth_greenpak4_part621 synth_greenpak4_part620 synth_greenpak4_part140))
......
......@@ -14,7 +14,7 @@ touch .start
if echo "$1" | grep ".*_error"; then
expected_string=""
#Change checked string for check other errors
# Change checked string for check other errors
if echo "$2" | grep ".*_fully_selected"; then
expected_string="ERROR: This command only operates on fully selected designs!"
elif [ "$2" = "synth_greenpak4_invalid_part" ]; then
......@@ -37,12 +37,17 @@ if echo "$1" | grep ".*_error"; then
fi
else
yosys -ql yosys.log ../../scripts/$2.ys
if [ $? != 0 ] ; then
echo FAIL > ${1}_${2}.status
if [ -f ../run-test.sh ]; then
../run-test.sh
touch .stamp
exit 0
else
yosys -ql yosys.log ../../scripts/$2.ys
if [ $? != 0 ] ; then
echo FAIL > ${1}_${2}.status
touch .stamp
exit 0
fi
fi
if [ -f "../../../../../techlibs/common/simcells.v" ]; then
COMMON_PREFIX=../../../../../techlibs/common
......
#!/usr/bin/python3
N = 131
# Test 1: pos_clk_no_enable_no_init_not_inferred
for i in range(1,N+1):
with open('test1_%d.v' % i, 'w') as fp:
fp.write('''
module test1_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, output [width-1:0] q);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_PP_ r(.C(clk), .D(int[w][d]), .E(1'b1), .Q(int[w][d+1]));
end
assign q[w] = int[w][depth];
end
endgenerate
endmodule
'''.format(i))
# Test 2: pos_clk_with_enable_no_init_not_inferred
for i in range(1,N+1):
with open('test2_%d.v' % i, 'w') as fp:
fp.write('''
module test2_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, input e, output [width-1:0] q);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_PP_ r(.C(clk), .D(int[w][d]), .E(e), .Q(int[w][d+1]));
end
assign q[w] = int[w][depth];
end
endgenerate
endmodule
'''.format(i))
# Test 3: pos_clk_with_enable_with_init_inferred
for i in range(1,N+1):
with open('test3_%d.v' % i, 'w') as fp:
fp.write('''
module test3_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, input e, output [width-1:0] q);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(posedge clk) if (e) int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(posedge clk) if (e) int[w] <= {{ int[w][depth-2:0], i[w] }};
assign q[w] = int[w][depth-1];
end
end
endgenerate
endmodule
'''.format(i))
# Test 4: neg_clk_no_enable_no_init_not_inferred
for i in range(1,N+1):
with open('test4_%d.v' % i, 'w') as fp:
fp.write('''
module test4_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, output [width-1:0] q);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_NP_ r(.C(clk), .D(int[w][d]), .E(1'b1), .Q(int[w][d+1]));
end
assign q[w] = int[w][depth];
end
endgenerate
endmodule
'''.format(i))
# Test 5: neg_clk_no_enable_no_init_inferred
for i in range(1,N+1):
with open('test5_%d.v' % i, 'w') as fp:
fp.write('''
module test5_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, output [width-1:0] q);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
if (depth == 1) begin
always @(negedge clk) int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk) int[w] <= {{ int[w][depth-2:0], i[w] }};
assign q[w] = int[w][depth-1];
end
end
endgenerate
endmodule
'''.format(i))
# Test 6: neg_clk_with_enable_with_init_inferred
for i in range(1,N+1):
with open('test6_%d.v' % i, 'w') as fp:
fp.write('''
module test6_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, input e, output [width-1:0] q);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(negedge clk) if (e) int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk) if (e) int[w] <= {{ int[w][depth-2:0], i[w] }};
assign q[w] = int[w][depth-1];
end
end
endgenerate
endmodule
'''.format(i))
# Test 10: pos_clk_no_enable_no_init_not_inferred_var_len
for i in range(1,N+1):
with open('test10_%d.v' % i, 'w') as fp:
fp.write('''
module test10_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, input [31:0] l, output [width-1:0] q);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_PP_ r(.C(clk), .D(int[w][d]), .E(1'b1), .Q(int[w][d+1]));
end
wire [depth-1:0] t;
assign t = int[w][depth:1];
assign q[w] = t[l];
end
endgenerate
endmodule
'''.format(i))
# Test 11: neg_clk_with_enable_with_init_inferred_var_len
for i in range(1,N+1):
with open('test11_%d.v' % i, 'w') as fp:
fp.write('''
module test11_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, input e, input [31:0] l, output [width-1:0] q);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(negedge clk) if (e) int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk) if (e) int[w] <= {{ int[w][depth-2:0], i[w] }};
assign q[w] = int[w][l];
end
end
endgenerate
endmodule
'''.format(i))
# Test 15: pos_clk_no_enable_no_init_not_inferred
for i in range(128+1,128+N+1):
with open('test15_%d.v' % i, 'w') as fp:
fp.write('''
module test15_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, output [width-1:0] q);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_PP_ r(.C(clk), .D(int[w][d]), .E(1'b1), .Q(int[w][d+1]));
end
assign q[w] = int[w][depth];
end
endgenerate
endmodule
'''.format(i))
# Test 16: neg_clk_with_enable_with_init_inferred_var_len
for i in range(128+1,128+N+1):
with open('test16_%d.v' % i, 'w') as fp:
fp.write('''
module test16_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, input e, input [31:0] l, output [width-1:0] q);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(negedge clk) if (e) int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk) if (e) int[w] <= {{ int[w][depth-2:0], i[w] }};
assign q[w] = int[w][l];
end
end
endgenerate
endmodule
'''.format(i))
# Test 18: neg_clk_with_enable_with_init_inferred2
for i in range(1,N+1):
with open('test18_%d.v' % i, 'w') as fp:
fp.write('''
module test18_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, input e, output [width-1:0] q);
generate
reg [width-1:0] int [depth-1:0];
genvar w, d;
for (d = 0; d < depth; d=d+1) begin
for (w = 0; w < width; w=w+1) begin
initial int[d][w] <= ~((d+w) % 2);
if (d == 0) begin
always @(negedge clk) if (e) int[d][w] <= i[w];
end
else begin
always @(negedge clk) if (e) int[d][w] <= int[d-1][w];
end
end
end
assign q = int[depth-1];
endgenerate
endmodule'''.format(i))
# Test 19: pos_clk_with_enable_no_init_inferred2_var_len
for i in range(1,N+1):
with open('test19_%d.v' % i, 'w') as fp:
fp.write('''
module test19_{0} #(parameter width=1, depth={0}) (input clk, input [width-1:0] i, input e, input [31:0] l, output [width-1:0] q);
generate
reg [width-1:0] int [depth-1:0];
genvar w, d;
for (d = 0; d < depth; d=d+1) begin
for (w = 0; w < width; w=w+1) begin
initial int[d][w] <= ~((d+w) % 2);
if (d == 0) begin
always @(posedge clk) if (e) int[d][w] <= i[w];
end
else begin
always @(posedge clk) if (e) int[d][w] <= int[d-1][w];
end
end
end
assign q = int[l];
endgenerate
endmodule'''.format(i))
#!/bin/bash
shopt -s extglob
OPTIND=1
seed="" # default to no seed specified
while getopts "S:" opt
do
case "$opt" in
S) arg="${OPTARG#"${OPTARG%%[![:space:]]*}"}" # remove leading space
seed="SEED=$arg" ;;
esac
done
shift "$((OPTIND-1))"
# check for Icarus Verilog
if ! which iverilog > /dev/null ; then
echo "$0: Error: Icarus Verilog 'iverilog' not found."
exit 1
fi
wget https://raw.githubusercontent.com/YosysHQ/yosys-bench/master/verilog/benchmarks_small/lfsr/generate.py -O generate_lfsr.py -o /dev/null
python3 generate_lfsr.py
python3 ../generate.py
cp ../*.v .
${MAKE:-make} -f ../../../../tools/autotest.mk $seed !(test21*).v EXTRA_FLAGS="-f 'verilog -noblackbox -icells' -p 'synth_xilinx' -l ../../../../../techlibs/xilinx/cells_sim.v"
${MAKE:-make} -f ../../../../tools/autotest.mk $seed test21*.v EXTRA_FLAGS="-f 'verilog -noblackbox -icells' -p 'synth_xilinx -retime' -l ../../../../../techlibs/xilinx/cells_sim.v"
cp ../*.ys .
for ys in *.ys; do
yosys -q $ys
done
# Check that non chain users block SRLs
design -reset; read_verilog test13a.out/test13a_syn0.v; select t:SRL* -assert-count 0
design -reset; read_verilog test13b.out/test13b_syn0.v; select t:SRL* -assert-count 0
design -reset; read_verilog test13c.out/test13c_syn0.v; select t:SRL* -assert-count 0
design -reset; read_verilog test13d.out/test13d_syn0.v; select t:SRL* -assert-count 0
// Check that non chain users block SRLs
// (i.e. output port, in non flattened case)
// sr_fixed_length_other_users_port
module test13a #(parameter width=1, depth=130) (input clk, input [width-1:0] i, output [width-1:0] q, output [depth-1:0] state);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_PP_ r(.C(clk), .D(int[w][d]), .E(1'b1), .Q(int[w][d+1]));
end
assign q[w] = int[w][depth];
end
assign state = int[0][depth:1];
endgenerate
endmodule
// Check that non chain users block SRLs
// (i.e. output port, in non flattened case)
// sr_var_length_other_users_port
module test13b #(parameter width=1, depth=130) (input clk, input [width-1:0] i, input e, input [31:0] l, output [width-1:0] q, output [depth-1:0] state);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(negedge clk) if (e) int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk) if (e) int[w] <= {{ int[w][depth-2:0], i[w] }};
assign q[w] = int[w][l];
end
end
assign state = int[0];
endgenerate
endmodule
// Check that non chain users block SRLs
// (i.e. output port, in non flattened case)
// sr_fixed_length_other_users_xor
module test13c #(parameter width=1, depth=130) (input clk, input [width-1:0] i, input e, output [width-1:0] q, output [depth-1:0] state);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_PP_ r(.C(clk), .D(int[w][d]), .E(1'b1), .Q(int[w][d+1]));
end
assign q[w] = int[w][depth];
end
assign state = int[0][depth:1];
endgenerate
endmodule
// Check that non chain users block SRLs
// (i.e. output port, in non flattened case)
// sr_var_length_other_users_xor
module test13c #(parameter width=1, depth=130) (input clk, input [width-1:0] i, input e, input [31:0] l, output [width-1:0] q, output [depth-1:0] state);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(negedge clk) if (e) int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk) if (e) int[w] <= {{ int[w][depth-2:0], i[w] }};
assign q[w] = int[w][l];
end
end
assign state = {depth{^int[0]}};
endgenerate
endmodule
design -reset; read_verilog test17a.out/test17a_syn0.v; select t:SRL16E -assert-count 1; select t:* t:SRL16E %d -assert-count 0;
design -reset; read_verilog test17b.out/test17b_syn0.v; select t:SRL16E -assert-count 1; select t:* t:SRL16E %d -assert-count 0;
design -reset; read_verilog test17c.out/test17c_syn0.v; select t:SRL16E -assert-count 2; select t:* t:SRL16E %d -assert-count 0;
design -reset; read_verilog test17d.out/test17d_syn0.v; select t:SRL16E -assert-count 2; select t:FD* -assert-count 1; select t:* t:SRL16E %d t:FD* %d -assert-count 0;
design -reset; read_verilog test17e.out/test17e_syn0.v; select t:SRL16E -assert-count 1; select t:* t:SRL16E %d -assert-count 0;
// Check inference even when not in vector
module test17a (input clk, input i, output q);
generate
reg a1, a2, a3, a4, a5, a6, a7, a8;
always @(posedge clk) a1 <= i;
always @(posedge clk) a2 <= a1;
always @(posedge clk) a3 <= a2;
always @(posedge clk) a4 <= a3;
always @(posedge clk) a5 <= a4;
always @(posedge clk) a6 <= a5;
always @(posedge clk) a7 <= a6;
always @(posedge clk) a8 <= a7;
assign q = a8;
endgenerate
endmodule
// Check inference even when not in vector
module test17a (input clk, input i, input e, output q);
generate
reg a1, a2, a3, a4, a5, a6, a7, a8;
always @(posedge clk) if (e) {a8,a7,a6,a5,a4,a3,a2,a1} <= {a7,a6,a5,a4,a3,a2,a1,i};
assign q = a8;
endgenerate
endmodule
// Check inference even when keep attribute specified
module test17c (input clk, input i, input e, output q);
generate
reg a1, a2, a3;
(* keep *) reg a4;
reg a5, a6, a7, a8;
always @(negedge clk) if (e) {a8,a7,a6,a5,a4,a3,a2,a1} <= {a7,a6,a5,a4,a3,a2,a1,i};
assign q = a8;
endgenerate
endmodule
// Check inference even when keep attribute specified
module test17d (input clk, input i, input e, output q);
generate
reg a1, a2;
(* keep *) reg a3;
(* keep *) reg a4;
reg a5, a6, a7, a8;
always @(negedge clk) if (e) {a8,a7,a6,a5,a4,a3,a2,a1} <= {a7,a6,a5,a4,a3,a2,a1,i};
assign q = a8;
endgenerate
endmodule
// Check inference even when keep attribute specified
module test17d (input clk, input i, input e, output q);
generate
reg a1, a2;
(* blah *) reg a3;
reg a4, a5, a6;
(* boo *) reg a7;
reg a8;
always @(negedge clk) if (e) {a8,a7,a6,a5,a4,a3,a2,a1} <= {a7,a6,a5,a4,a3,a2,a1,i};
assign q = a8;
endgenerate
endmodule
module test20 #(parameter width=130, depth=130) (input clk, input [width-1:0] i, input e, output [width-1:0] q);
generate
reg [width-1:0] int [depth-1:0];
genvar w, d;
for (d = 0; d < depth; d=d+1) begin
for (w = 0; w < width; w=w+1) begin
initial int[d][w] <= ~((d+w) % 2);
if (d == 0) begin
always @(negedge clk) if (e) int[d][w] <= i[w];
end
else begin
always @(negedge clk) if (e) int[d][w] <= int[d-1][w];
end
end
end
assign z = int[depth-1];
endgenerate
endmodule
design -reset; read_verilog test20.out/test20_syn0.v; select t:FD* -assert-count 0
# Check that retiming does not infer shift registers
design -reset; read_verilog test21a.out/test21a_syn0.v; select t:SRL* -assert-count 0; select t:FD* -assert-min 20
design -reset; read_verilog test21b.out/test21b_syn0.v; select t:SRL* -assert-count 0; select t:FD* -assert-min 20
module test21a #(parameter width=130, depth=4) (input clk, input [width-1:0] i, output q);
genvar d;
wire [depth:0] int;
assign int[0] = ^i[width-1:0];
generate
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_PP_ r(.C(clk), .D(int[d]), .E(1'b1), .Q(int[d+1]));
end
endgenerate
assign q = int[depth];
endmodule
module test21b #(parameter width=130, depth=4) (input clk, input [width-1:0] i, input e, output q);
reg [depth-1:0] int;
genvar d;
for (d = 0; d < depth; d=d+1)
initial int[d] <= ~(d % 2);
if (depth == 1) begin
always @(negedge clk) if (e) int <= ~^i[width-1:0];
assign q = int;
end
else begin
always @(negedge clk) if (e) int <= { int[depth-2:0], ~^i[width-1:0] };
assign q = int[depth-1];
end
endmodule
# Check that shift registers with resets are not inferred into SRLs
design -reset; read_verilog test7a.out/test7a_syn0.v; select t:SRL* -assert-count 0
design -reset; read_verilog test7b.out/test7b_syn0.v; select t:SRL* -assert-count 0
design -reset; read_verilog test7c.out/test7c_syn0.v; select t:SRL* -assert-count 0
design -reset; read_verilog test7d.out/test7d_syn0.v; select t:SRL* -assert-count 0
// Check that use of resets block shreg
// pos_clk_no_enable_no_init_not_inferred_with_reset
module test7a #(parameter width=1, depth=130) (input clk, input [width-1:0] i, input r, output [width-1:0] q);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFF_PP0_ r(.C(clk), .D(int[w][d]), .R(r), .Q(int[w][d+1]));
end
assign q[w] = int[w][depth];
end
endgenerate
endmodule
// Check that use of resets block shreg
// neg_clk_no_enable_with_init_with_inferred_with_reset
module test7b #(parameter width=1, depth=130) (input clk, input [width-1:0] i, input r, output [width-1:0] q);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(negedge clk or posedge r) if (r) int[w] <= 1'b0; else int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk or posedge r) if (r) int[w] <= {width{1'b0}}; else int[w] <= { int[w][depth-2:0], i[w] };
assign q[w] = int[w][depth-1];
end
end
endgenerate
endmodule
// Check that use of resets block shreg
// pos_clk_no_enable_no_init_not_inferred_with_reset_var_len
module test7c #(parameter width=1, depth=130) (input clk, input [width-1:0] i, input r, input [31:0] l, output [width-1:0] q);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFF_PP0_ r(.C(clk), .D(int[w][d]), .R(r), .Q(int[w][d+1]));
end
wire [depth-1:0] t;
assign t = int[w][depth:1];
assign q[w] = t[l];
end
endgenerate
endmodule
// Check that use of resets block shreg
// neg_clk_no_enable_with_init_with_inferred_with_reset_var_len
module test7d #(parameter width=1, depth=130) (input clk, input [width-1:0] i, input r, input [31:0] l, output [width-1:0] q);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(negedge clk or posedge r) if (r) int[w] <= 1'b0; else int[w] <= a[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk or posedge r) if (r) int[w] <= {width{1'b0}}; else int[w] <= {{ int[w][depth-2:0], i[w] }};
assign q[w] = int[w][l];
end
end
endgenerate
endmodule
// Check multi-bit works
// pos_clk_no_enable_no_init_not_inferred_N_width
module test8 #(parameter width=130, depth=130) (input clk, input [width-1:0] i, output [width-1:0] q);
generate
wire [depth:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
assign int[w][0] = i[w];
for (d = 0; d < depth; d=d+1) begin
\$_DFFE_PP_ r(.C(clk), .D(int[w][d]), .E(1'b0), .Q(int[w][d+1]));
end
assign q[w] = int[w][depth];
end
endgenerate
endmodule
# Check that wide shift registers are not a problem
read_verilog test8.out/test8_syn0.v; select t:FD* -assert-count 0
// Check multi-bit works
// neg_clk_no_enable_with_init_with_inferred_N_width
module test9 #(parameter width=130, depth=130) (input clk, input [width-1:0] i, output [width-1:0] q);
generate
reg [depth-1:0] int [width-1:0];
genvar w, d;
for (w = 0; w < width; w=w+1) begin
for (d = 0; d < depth; d=d+1)
initial int[w][d] <= ~((d+w) % 2);
if (depth == 1) begin
always @(negedge clk) int[w] <= i[w];
assign q[w] = int[w];
end
else begin
always @(negedge clk) int[w] <= { int[w][depth-2:0], i[w] };
assign q[w] = int[w][depth-1];
end
end
endgenerate
endmodule
read_verilog test9.out/test9_syn0.v; select t:FD* -assert-count 0
design -reset; read_verilog ug901a.out/ug901a_syn0.v; select t:SRLC32E -assert-count 1
design -reset; read_verilog ug901b.out/ug901b_syn0.v; select t:SRLC32E -assert-count 1
design -reset; read_verilog ug901c.out/ug901c_syn0.v; select t:SRLC32E -assert-count 1
// https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug901-vivado-synthesis.pdf
// 8-bit Shift Register
// Rising edge clock
// Active high clock enable
// Concatenation-based template
// File: shift_registers_0.v
module shift_registers_0 (clk, clken, SI, SO);
parameter WIDTH = 32;
input clk, clken, SI;
output SO;
reg [WIDTH-1:0] shreg;
always @(posedge clk)
begin
if (clken)
shreg <= {shreg[WIDTH-2:0], SI};
end
assign SO = shreg[WIDTH-1];
endmodule
// https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug901-vivado-synthesis.pdf
// 32-bit Shift Register
// Rising edge clock
// Active high clock enable
// For-loop based template
// File: shift_registers_1.v
module shift_registers_1 (clk, clken, SI, SO);
parameter WIDTH = 32;
input clk, clken, SI;
output SO;
reg [WIDTH-1:0] shreg;
integer i;
always @(posedge clk)
begin
if (clken)
begin
for (i = 0; i < WIDTH-1; i = i+1)
shreg[i+1] <= shreg[i];
shreg[0] <= SI;
end
end
assign SO = shreg[WIDTH-1];
endmodule
// https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_3/ug901-vivado-synthesis.pdf
// 32-bit dynamic shift register.
// Download:
// File: dynamic_shift_registers_1.v
module dynamic_shift_register_1 (CLK, CE, SEL, SI, DO);
parameter SELWIDTH = 5;
input CLK, CE, SI;
input [SELWIDTH-1:0] SEL;
output DO;
localparam DATAWIDTH = 2**SELWIDTH;
reg [DATAWIDTH-1:0] data;
assign DO = data[SEL];
always @(posedge CLK)
begin
if (CE == 1'b1)
data <= {data[DATAWIDTH-2:0], SI};
end
endmodule
......@@ -30,8 +30,9 @@ $(eval $(call template,issue_00041,issue_00041))
$(eval $(call template,issue_00059,issue_00059))
#issue_00065
# Takes too long
#$(eval $(call template,issue_00065,issue_00065))
ifeq ($(ENABLE_HEAVY_TESTS),1)
$(eval $(call template,issue_00065,issue_00065))
endif
#issue_00067
$(eval $(call template,issue_00067,issue_00067))
......@@ -299,8 +300,9 @@ $(eval $(call template,issue_00763,issue_00763))
$(eval $(call template,issue_00767,issue_00767))
#issue_00774
# Takes too long
#$(eval $(call template,issue_00774,issue_00774))
ifeq ($(ENABLE_HEAVY_TESTS),1)
$(eval $(call template,issue_00774,issue_00774))
endif
#issue_00781
$(eval $(call template,issue_00781,issue_00781))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment