Add compat divide module and tb
This commit is contained in:
@@ -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
|
||||
160
rtl/compat/VX_tb_divide.sv
Normal file
160
rtl/compat/VX_tb_divide.sv
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user