From 0211ca4add34c650a0a28f9af0d34c4fa568b70c Mon Sep 17 00:00:00 2001 From: wgulian3 Date: Tue, 4 Feb 2020 10:59:05 -0500 Subject: [PATCH] Add compat divide module and tb --- rtl/compat/VX_divide.v | 113 ++++++++++++++++++++++++++ rtl/compat/VX_tb_divide.sv | 160 +++++++++++++++++++++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 rtl/compat/VX_tb_divide.sv diff --git a/rtl/compat/VX_divide.v b/rtl/compat/VX_divide.v index e69de29b..ea5e8be7 100644 --- a/rtl/compat/VX_divide.v +++ b/rtl/compat/VX_divide.v @@ -0,0 +1,113 @@ +module VX_divide + #( + parameter WIDTHN=1, + parameter WIDTHD=1, + parameter NREP="UNSIGNED", + parameter DREP="UNSIGNED", + parameter SPEED="MIXED", // "MIXED" or "HIGHEST" + parameter PIPELINE=0 + ) + ( + input clock, aclr, clken, + + input [WIDTHN-1:0] numer, + input [WIDTHD-1:0] denom, + + output [WIDTHN-1:0] quotient, + output [WIDTHD-1:0] remainder + ); + +// synthesis read_comments_as_HDL on +// localparam IMPL = "quartus"; +// synthesis read_comments_as_HDL off + +// altera translate_off + localparam IMPL="fallback"; +// altera translate_on + + generate + if (NREP != DREP) begin + different_nrep_drep_not_yet_supported non_existing_module(); + end + + if (IMPL == "quartus") begin + + localparam lpm_speed=SPEED == "HIGHEST" ? 9:5; + + lpm_divide#( + .LPM_WIDTHN(WIDTHN), + .LPM_WIDTHD(WIDTHD), + .LPM_NREPRESENTATION(NREP), + .LPM_DREPRESENTATION(DREP), + .LPM_PIPELINE(PIPELINE), + .LPM_REMAINDERPOSITIVE("FALSE"), // emulate verilog % operator + .MAXIMIZE_SPEED(lpm_speed) + ) quartus_divider( + .clock(clock), + .aclr(aclr), + .clken(clken), + .numer(numer), + .denom(denom), + .quotient(quotient), + .remainder(remainder) + ); + + end + else if (PIPELINE == 0) begin + if (NREP == "SIGNED") begin + assign quotient = $signed($signed(numer)/$signed(denom)); + assign remainder = $signed($signed(numer)%$signed(denom)); + end + else begin + assign quotient = numer/denom; + assign remainder = numer%denom; + end + end + else begin + + reg [WIDTHN-1:0] numer_pipe [0:PIPELINE-1]; + reg [WIDTHD-1:0] denom_pipe [0:PIPELINE-1]; + + genvar pipe_stage; + for (pipe_stage = 0; pipe_stage < PIPELINE-1; pipe_stage = pipe_stage+1) begin : pipe_stages + always @(posedge clock or posedge aclr) begin + if (aclr) begin + numer_pipe[pipe_stage+1] <= 0; + denom_pipe[pipe_stage+1] <= 0; + end + else if (clken) begin + numer_pipe[pipe_stage+1] <= numer_pipe[pipe_stage]; + denom_pipe[pipe_stage+1] <= denom_pipe[pipe_stage]; + end + end + end + + always @(posedge clock or posedge aclr) begin + if (aclr) begin + numer_pipe[0] <= 0; + denom_pipe[0] <= 0; + end + else if (clken) begin + numer_pipe[0] <= numer; + denom_pipe[0] <= denom; + end + end + + wire [WIDTHN-1:0] numer_pipe_end; + assign numer_pipe_end = numer_pipe[PIPELINE-1]; + wire [WIDTHD-1:0] denom_pipe_end; + assign denom_pipe_end = denom_pipe[PIPELINE-1]; + + if (NREP == "SIGNED") begin + assign quotient = $signed($signed(numer_pipe_end)/$signed(denom_pipe_end)); + assign remainder = $signed($signed(numer_pipe_end)%$signed(denom_pipe_end)); + end + else begin + assign quotient = numer_pipe_end/denom_pipe_end; + assign remainder = numer_pipe_end%denom_pipe_end; + end + + end + endgenerate + +endmodule: VX_divide \ No newline at end of file diff --git a/rtl/compat/VX_tb_divide.sv b/rtl/compat/VX_tb_divide.sv new file mode 100644 index 00000000..08342eac --- /dev/null +++ b/rtl/compat/VX_tb_divide.sv @@ -0,0 +1,160 @@ +`timescale 1ns/1ps + +module VX_tb_divide(); + + `ifdef TRACE + initial + begin + $dumpfile("trace.vcd"); + $dumpvars(0,test); + end + `endif + + reg clk; + reg rst; + + reg [31:0] numer, denom; + + wire [31:0] o_div[0:7], o_rem[0:7]; + + genvar i; + generate + for (i = 0; i < 8; i = i+1) begin : div_loop + VX_divide#( + .WIDTHN(32), + .WIDTHD(32), + .PIPELINE(i) + ) div( + .clock(clk), + .aclr(rst), + .clken(1'b1), + .numer(numer), + .denom(denom), + .quotient(o_div[i]), + .remainder(o_rem[i]) + ); + end + endgenerate + + initial begin + clk = 0; rst = 0; + + numer = 56; + denom = 11; + + $display("56 / 11 #0"); + if (o_div[0] != 5 || o_rem[0] != 1) begin + $display("PIPE0: div=", o_div[0], " rem=", o_rem[0]); + $display("expected 5,1 EXITING"); + $finish(); + end + + if (o_div[1] != 1'bx || o_rem[1] != 1'bx) begin + $display("PIPE1: div=", o_div[1], " rem=", o_rem[1]); + $display("expected x,x EXITING"); + $finish(); + end + + if (o_div[2] != 1'bx || o_rem[2] != 1'bx) begin + $display("PIPE2: div=", o_div[2], " rem=", o_rem[2]); + $display("expected x,x EXITING"); + $finish(); + end + + if (o_div[3] != 1'bx || o_rem[3] != 1'bx) begin + $display("PIPE3: div=", o_div[3], " rem=", o_rem[3]); + $display("expected x,x EXITING"); + $finish(); + end + + #2; + + $display("56 / 11 #2"); + if (o_div[0] != 5 || o_rem[0] != 1) begin + $display("PIPE0: div=", o_div[0], " rem=", o_rem[0]); + $display("expected 5,1, EXITING"); + $finish(); + end + + if (o_div[1] != 5 || o_rem[1] != 1) begin + $display("PIPE1: div=", o_div[1], " rem=", o_rem[1]); + $display("expected 5,1 EXITING"); + $finish(); + end + + if (o_div[2] != 1'bx || o_rem[2] != 1'bx) begin + $display("PIPE2: div=", o_div[2], " rem=", o_rem[2]); + $display("expected x,x EXITING"); + $finish(); + end + + if (o_div[3] != 1'bx || o_rem[3] != 1'bx) begin + $display("PIPE3: div=", o_div[3], " rem=", o_rem[3]); + $display("expected x,x EXITING"); + $finish(); + end + + #2; + + $display("56 / 11 #4"); + if (o_div[0] != 5 || o_rem[0] != 1) begin + $display("PIPE0: div=", o_div[0], " rem=", o_rem[0]); + $display("expected 5,1 EXITING"); + $finish(); + end + + if (o_div[1] != 5 || o_rem[1] != 1) begin + $display("PIPE1: div=", o_div[1], " rem=", o_rem[1]); + $display("expected 5,1 EXITING"); + $finish(); + end + + if (o_div[2] != 5 || o_rem[2] != 1) begin + $display("PIPE2: div=", o_div[2], " rem=", o_rem[2]); + $display("expected 5,1 EXITING"); + $finish(); + end + + if (o_div[3] != 1'bx || o_rem[3] != 1'bx) begin + $display("PIPE3: div=", o_div[3], " rem=", o_rem[3]); + $display("expected x,x EXITING"); + $finish(); + end + + #2; + + $display("56 / 11 #6"); + + if (o_div[0] != 5 || o_rem[0] != 1) begin + $display("PIPE0: div=", o_div[0], " rem=", o_rem[0]); + $display("expected 5,1 EXITING"); + $finish(); + end + + if (o_div[1] != 5 || o_rem[1] != 1) begin + $display("PIPE1: div=", o_div[1], " rem=", o_rem[1]); + $display("expected 5,1 EXITING"); + $finish(); + end + + if (o_div[2] != 5 || o_rem[2] != 1) begin + $display("PIPE2: div=", o_div[2], " rem=", o_rem[2]); + $display("expected 5,1 EXITING"); + $finish(); + end + + if (o_div[3] != 5 || o_rem[3] != 1) begin + $display("PIPE3: div=", o_div[3], " rem=", o_rem[3]); + $display("expected 5,1 EXITING"); + $finish(); + end + + $display("PASS"); + + $finish(); + end + + always #1 + clk = ~clk; + +endmodule: VX_tb_divide \ No newline at end of file