| #!/bin/bash |
| set -ex |
| |
| for iter in {1..100} |
| do |
| SZA=$(( 3 + $RANDOM % 13 )) |
| SZB=$(( 3 + $RANDOM % 13 )) |
| SZO=$(( 3 + $RANDOM % 29 )) |
| |
| C0=clk$(( $RANDOM & 1)) |
| C1=clk$(( $RANDOM & 1)) |
| C2=clk$(( $RANDOM & 1)) |
| C3=clk$(( $RANDOM & 1)) |
| |
| E0=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge ) |
| E1=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge ) |
| E2=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge ) |
| E3=$( test $(( $RANDOM & 1 )) -eq 0 && echo posedge || echo negedge ) |
| |
| SP=$( test $(( $RANDOM & 1 )) -eq 0 && echo S || echo P ) |
| |
| RC=$( test $(( $RANDOM & 1 )) -eq 0 && echo "reset" || echo "!reset" ) |
| RV="32'h$( echo $RANDOM | md5sum | cut -c1-8 )" |
| |
| cat > test_dsp_map_top.v << EOT |
| module top ( |
| input clk0, clk1, reset, |
| input [$SZA:0] A, |
| input [$SZB:0] B, |
| output [$SZO:0] O |
| ); |
| reg [15:0] AA, BB; |
| reg [31:0] P, S; |
| |
| always @($E0 $C0) AA <= A; |
| always @($E1 $C1) BB <= B; |
| always @($E2 $C2) P <= AA * BB; |
| always @($E3 $C3) S <= $RC ? $RV : S + P; |
| assign O = $SP; |
| endmodule |
| EOT |
| |
| cat > test_dsp_map_tb.v << EOT |
| \`timescale 1ns / 1ps |
| module testbench; |
| reg clk1, clk0, reset; |
| reg [$SZA:0] A; |
| reg [$SZB:0] B; |
| |
| wire [$SZO:0] O_top, O_syn; |
| |
| top top_inst (.clk0(clk0), .clk1(clk1), .reset(reset), .A(A), .B(B), .O(O_top)); |
| syn syn_inst (.clk0(clk0), .clk1(clk1), .reset(reset), .A(A), .B(B), .O(O_syn)); |
| |
| initial begin |
| // \$dumpfile("test_dsp_map.vcd"); |
| // \$dumpvars(0, testbench); |
| |
| #2; |
| clk0 = 0; |
| clk1 = 0; |
| reset = 1; |
| reset = $RC; |
| A = 0; |
| B = 0; |
| |
| repeat (3) begin |
| #2; clk0 = ~clk0; |
| #2; clk0 = ~clk0; |
| #2; clk1 = ~clk1; |
| #2; clk1 = ~clk1; |
| end |
| |
| repeat (100) begin |
| #2; |
| A = \$urandom; |
| B = \$urandom; |
| reset = \$urandom & \$urandom & \$urandom & \$urandom; |
| if (\$urandom & 1) begin |
| #2; clk0 = ~clk0; |
| #2; clk0 = ~clk0; |
| end else begin |
| #2; clk1 = ~clk1; |
| #2; clk1 = ~clk1; |
| end |
| #2; |
| if (O_top !== O_syn) begin |
| \$display("ERROR: O_top=%b O_syn=%b", O_top, O_syn); |
| \$stop; |
| end |
| // \$display("OK O_top=O_syn=%b", O_top); |
| end |
| |
| \$display("Test passed."); |
| \$finish; |
| end |
| endmodule |
| EOT |
| |
| ../../../yosys -p 'read_verilog test_dsp_map_top.v; synth_ice40 -dsp; rename top syn; write_verilog test_dsp_map_syn.v' |
| iverilog -o test_dsp_map -s testbench test_dsp_map_tb.v test_dsp_map_top.v test_dsp_map_syn.v ../cells_sim.v |
| vvp -N test_dsp_map |
| done |
| |
| : "" |
| : "#### All tests passed. ####" |
| : "" |