diff --git a/bsg_misc/bsg_idiv_iterative.v b/bsg_misc/bsg_idiv_iterative.v index db670126d..35de1bd34 100644 --- a/bsg_misc/bsg_idiv_iterative.v +++ b/bsg_misc/bsg_idiv_iterative.v @@ -73,9 +73,28 @@ module bsg_idiv_iterative #(parameter width_p=32, parameter bitstack_p=0, parame ,.clk_i(clk_i) ); + logic [`BSG_SAFE_CLOG2(width_p)-1:0] clz_c_result, clz_a_result; + + bsg_counting_leading_zeros #( + .width_p(width_p) + ) clz_c ( + .a_i(dividend_i) + ,.num_zero_o(clz_c_result) + ); + + bsg_counting_leading_zeros #( + .width_p(width_p) + ) clz_a ( + .a_i(divisor_i) + ,.num_zero_o(clz_a_result) + ); + //if the divisor is zero wire zero_divisor_li = ~(| opA_r); + wire [`BSG_SAFE_CLOG2(width_p)-1:0] div_shift_li; + assign div_shift_li = zero_divisor_li ? width_p-1 : clz_a_result - clz_c_result; + wire [1:0] opA_sel_lo; wire [width_p:0] opA_mux; @@ -88,17 +107,18 @@ module bsg_idiv_iterative #(parameter width_p=32, parameter bitstack_p=0, parame wire [width_p:0] opB_mux, opC_mux; wire [bits_per_iter_p + 1:0] opB_sel_lo, opC_sel_lo; - + wire [`BSG_WIDTH(width_p):0] shift_val_lo; + if (bits_per_iter_p == 2) begin bsg_mux_one_hot #(.width_p(width_p+1), .els_p(4)) muxB - (.data_i( {opC_r, add1_out, {add1_out[width_p-1:0], opC_r[width_p]}, {add2_out[width_p-1:0], opC_r[width_p-1]}} ) + (.data_i( {opC_r, add1_out, {(add1_out << (width_p-shift_val_lo+1)) | opC_r >> (shift_val_lo)}, {add2_out[width_p-1:0], opC_r[width_p-1]}} ) ,.data_o( opB_mux ) ,.sel_one_hot_i(opB_sel_lo) ); bsg_mux_one_hot #(.width_p(width_p+1), .els_p(4)) muxC - (.data_i( {{dividend_msb, dividend_i},add1_out, {opC_r[width_p-1:0], ~add1_out[width_p]}, {opC_r[width_p-2:0], ~add1_out[width_p], ~add2_out[width_p]}}) + (.data_i( {{dividend_msb, dividend_i},add1_out, {(opC_r << (width_p-shift_val_lo+1)) | ((~add1_out >> width_p) << (width_p-shift_val_lo))}, {opC_r[width_p-2:0], ~add1_out[width_p], ~add2_out[width_p]}}) ,.data_o( opC_mux ) ,.sel_one_hot_i(opC_sel_lo) ); @@ -106,19 +126,19 @@ module bsg_idiv_iterative #(parameter width_p=32, parameter bitstack_p=0, parame end else begin bsg_mux_one_hot #(.width_p(width_p+1), .els_p(3)) muxB - (.data_i( {opC_r, add1_out, {add1_out[width_p-1:0], opC_r[width_p]}} ) + (.data_i( {opC_r, add1_out, {(add1_out << (width_p-shift_val_lo+1)) | opC_r >> shift_val_lo}} ) ,.data_o( opB_mux ) ,.sel_one_hot_i(opB_sel_lo) ); bsg_mux_one_hot #(.width_p(width_p+1), .els_p(3)) muxC - (.data_i( {{dividend_msb, dividend_i},add1_out, {opC_r[width_p-1:0], ~add1_out[width_p]}} ) + (.data_i( {{dividend_msb, dividend_i},add1_out, {(opC_r << (width_p-shift_val_lo+1)) | ((~add1_out >> width_p) << (width_p-shift_val_lo))}} ) ,.data_o( opC_mux ) - ,.sel_one_hot_i(opC_sel_lo) - ); + ,.sel_one_hot_i(opC_sel_lo) + ); end - + wire opA_ld_lo; bsg_dff_en#(.width_p(width_p+1)) opA_reg (.data_i (opA_mux) @@ -240,6 +260,8 @@ module bsg_idiv_iterative #(parameter width_p=32, parameter bitstack_p=0, parame ,.opA_is_neg_i (opA_r[width_p]) ,.opC_is_neg_i (opC_r[width_p]) + ,.div_shift_i (div_shift_li) + ,.opA_sel_o (opA_sel_lo) ,.opA_ld_o (opA_ld_lo) ,.opA_inv_o (opA_inv_lo) @@ -256,7 +278,10 @@ module bsg_idiv_iterative #(parameter width_p=32, parameter bitstack_p=0, parame ,.latch_signed_div_o (latch_signed_div_lo) ,.adder1_cin_o (adder1_cin_lo) + ,.shift_val_o (shift_val_lo) + ,.v_o(v_o) ,.yumi_i(yumi_i) ); + endmodule // divide diff --git a/bsg_misc/bsg_idiv_iterative_controller.v b/bsg_misc/bsg_idiv_iterative_controller.v index e06bf1204..aa2a79527 100644 --- a/bsg_misc/bsg_idiv_iterative_controller.v +++ b/bsg_misc/bsg_idiv_iterative_controller.v @@ -22,6 +22,8 @@ module bsg_idiv_iterative_controller #(parameter width_p=32, parameter bits_per_ ,input opA_is_neg_i ,input opC_is_neg_i + ,input [`BSG_SAFE_CLOG2(width_p)-1:0] div_shift_i + ,output logic [1:0] opA_sel_o ,output logic opA_ld_o ,output logic opA_inv_o @@ -38,6 +40,8 @@ module bsg_idiv_iterative_controller #(parameter width_p=32, parameter bits_per_ ,output logic latch_signed_div_o ,output logic adder1_cin_o + ,output logic [`BSG_WIDTH(width_p)-1:0] shift_val_o + ,output logic v_o ,input yumi_i ); @@ -46,7 +50,7 @@ module bsg_idiv_iterative_controller #(parameter width_p=32, parameter bits_per_ logic r_neg_r; logic neg_ld; logic add1_neg_last_r, add2_neg_last_r; - + typedef enum logic[5:0] {WAIT, NEG0, NEG1, SHIFT, CALC, @@ -67,9 +71,13 @@ module bsg_idiv_iterative_controller #(parameter width_p=32, parameter bits_per_ end end + wire [`BSG_WIDTH(width_p/bits_per_iter_p)-1:0] calc_cyc; + assign calc_cyc = ((!signed_div_r_i)) ? ((bits_per_iter_p==1)?div_shift_i:(div_shift_i+1)/2) : width_p/bits_per_iter_p; + assign shift_val_o = ((state == SHIFT) && ((!signed_div_r_i))) ? ((bits_per_iter_p==1)?div_shift_i:(calc_cyc*2)) : width_p; + logic [`BSG_WIDTH(width_p/bits_per_iter_p)-1:0] calc_cnt; - wire calc_up_li = (state == CALC) && (calc_cnt < width_p/bits_per_iter_p); - wire calc_done = (calc_cnt == width_p/bits_per_iter_p); + wire calc_up_li = (state == CALC) && (calc_cnt < calc_cyc); + wire calc_done = (calc_cnt == calc_cyc); bsg_counter_clear_up#(.max_val_p(width_p/bits_per_iter_p) ,.init_val_p(0) ,.disable_overflow_warning_p(1)) calc_counter diff --git a/testing/bsg_misc/bsg_idiv_iterative/Makefile b/testing/bsg_misc/bsg_idiv_iterative/Makefile index 0b619436d..30c5a20fd 100644 --- a/testing/bsg_misc/bsg_idiv_iterative/Makefile +++ b/testing/bsg_misc/bsg_idiv_iterative/Makefile @@ -1,16 +1,19 @@ # FIXME: set up VCS, should modified for different users. include ../../../../bsg_cadenv/cadenv.mk +export BASEJUMP_STL_DIR=$(abspath ../../..) +INCDIR = +incdir+$(BASEJUMP_STL_DIR)/bsg_misc PLI_OPTS = -P mypli.tab get_stim.c +acc VCS_OP += +vcs+vcdpluson -debug_access+all VCS_DEFINES = +CC = gcc +CFLAGS = -g +SRC=unsigned.c +SRC1=signed.c ifdef SIGN VCS_DEFINES += +define+SIGN=$(SIGN) endif -ifdef UNSIGN -VCS_DEFINES += +define+UNSIGN=$(UNSIGN) -endif ifdef WIDTH VCS_DEFINES += +define+WIDTH=$(WIDTH) endif @@ -22,13 +25,23 @@ VCS_DEFINES += +define+ITERS=$(ITERS) endif vcs: - $(VCS) -full64 -sverilog $(VCS_OP) -Mupdate -f divide.files $(LIB_OPTS) $(PLI_OPTS) $(VCS_DEFINES) + $(VCS) -full64 -sverilog $(VCS_OP) -Mupdate -f sv.include -f divide.files $(LIB_OPTS) $(PLI_OPTS) $(VCS_DEFINES) #./simv +vcs+stop+232100 ./simv xvcs: $(VCS) -full64 -sverilog -Mupdate -RI -line -f divide.files $(LIB_OPTS) $(PLI_OPTS) +test: $(SRC) + $(CC) -o unsigned.o -c $^ $(CFLAGS) -lm -std=c99 -D ITERS=$(ITERS) -D WIDTH=$(WIDTH) + $(CC) unsigned.o -o test + ./test + +test1: $(SRC1) + $(CC) -o signed.o -c $^ $(CFLAGS) -lm -std=c99 -D ITERS=$(ITERS) -D WIDTH=$(WIDTH) + $(CC) signed.o -o test1 + ./test1 + clean: $(RM) -r csrc simv.daidir vcs.key simv ucli.key vcdplus.vpd s_output.txt u_output.txt u.txt s.txt dve64: @@ -38,4 +51,4 @@ gtk: gtkwave vcd verify: egrep [0-9] u_expected.txt | diff -w u_output.txt - - egrep [0-9] s_expected.txt | diff -w s_output.txt - +# egrep [0-9] s_expected.txt | diff -w s_output.txt - diff --git a/testing/bsg_misc/bsg_idiv_iterative/README.md b/testing/bsg_misc/bsg_idiv_iterative/README.md index 326448b3a..74fd30f98 100644 --- a/testing/bsg_misc/bsg_idiv_iterative/README.md +++ b/testing/bsg_misc/bsg_idiv_iterative/README.md @@ -1,7 +1,6 @@ Testbench: - Set design parameters for design like bits/iteration and design width in the make command -UNSIGN - Test unsigned (default don't test) SIGN - Test signed (default don't test) WIDTH - design width BITS_PER_ITER - 1 or 2 bits per iteration generated (different hardware designs) diff --git a/testing/bsg_misc/bsg_idiv_iterative/signed.c b/testing/bsg_misc/bsg_idiv_iterative/signed.c index cf6f37926..afa0255b1 100644 --- a/testing/bsg_misc/bsg_idiv_iterative/signed.c +++ b/testing/bsg_misc/bsg_idiv_iterative/signed.c @@ -3,8 +3,12 @@ // RISC-V ISA Manual: Section 7.2 - Division Operations #include #include +#ifndef WIDTH #define WIDTH 4 +#endif +#ifndef ITERS #define ITERS 1 << (WIDTH * 2) +#endif // #define ITERS 10000 // Function to compute quotient diff --git a/testing/bsg_misc/bsg_idiv_iterative/sv.include b/testing/bsg_misc/bsg_idiv_iterative/sv.include new file mode 100644 index 000000000..2572ec4f3 --- /dev/null +++ b/testing/bsg_misc/bsg_idiv_iterative/sv.include @@ -0,0 +1,5 @@ +$BASEJUMP_STL_DIR/bsg_misc/bsg_counting_leading_zeros.v +$BASEJUMP_STL_DIR/bsg_misc/bsg_priority_encode.v +$BASEJUMP_STL_DIR/bsg_misc/bsg_priority_encode_one_hot_out.v +$BASEJUMP_STL_DIR/bsg_misc/bsg_encode_one_hot.v +$BASEJUMP_STL_DIR/bsg_misc/bsg_scan.v diff --git a/testing/bsg_misc/bsg_idiv_iterative/test_bsg.v b/testing/bsg_misc/bsg_idiv_iterative/test_bsg.v index bdc6ee105..32b2232ef 100644 --- a/testing/bsg_misc/bsg_idiv_iterative/test_bsg.v +++ b/testing/bsg_misc/bsg_idiv_iterative/test_bsg.v @@ -95,10 +95,8 @@ module test_bsg; $fwrite(f1,"%d %d %d %d\n", s_dividend, s_divisor, s_quotient, s_remainder); $fwrite(f3,"%d %d\n", s_dividend, s_divisor); - `endif - // do the unsigned case - `ifdef UNSIGN + `else u_dividend = dividend; u_divisor = divisor; diff --git a/testing/bsg_misc/bsg_idiv_iterative/unsigned.c b/testing/bsg_misc/bsg_idiv_iterative/unsigned.c index f980dfd3c..f54078be6 100644 --- a/testing/bsg_misc/bsg_idiv_iterative/unsigned.c +++ b/testing/bsg_misc/bsg_idiv_iterative/unsigned.c @@ -1,12 +1,16 @@ -// Program to produce a file with the expected output +//jl Program to produce a file with the expected output // for all possible inputs to an unsigned 4-bit divider pursuant to // RISC-V ISA Manual: Section 7.2 - Division Operations #include #include #include +#ifndef WIDTH #define WIDTH 4 +#endif +#ifndef ITERS #define ITERS 1 << (WIDTH*2) +#endif // #define ITERS 10000 // Function to compute quotient