391 lines
14 KiB
Verilog
391 lines
14 KiB
Verilog
// =============================================================================
|
|
// Generated by efx_ipmgr
|
|
// Version: 2023.1.150
|
|
// IP Version: 5.0
|
|
// =============================================================================
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2013-2023 Efinix Inc. All rights reserved.
|
|
//
|
|
// This document contains proprietary information which is
|
|
// protected by copyright. All rights are reserved. This notice
|
|
// refers to original work by Efinix, Inc. which may be derivitive
|
|
// of other work distributed under license of the authors. In the
|
|
// case of derivative work, nothing in this notice overrides the
|
|
// original author's license agreement. Where applicable, the
|
|
// original license agreement is included in it's original
|
|
// unmodified form immediately below this header.
|
|
//
|
|
// WARRANTY DISCLAIMER.
|
|
// THE DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND
|
|
// EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH
|
|
// RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,
|
|
// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE. SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED
|
|
// WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.
|
|
//
|
|
// LIMITATION OF LIABILITY.
|
|
// NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY
|
|
// INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT
|
|
// MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY
|
|
// OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,
|
|
// SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY
|
|
// CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
|
|
// GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR
|
|
// MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN
|
|
// THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER
|
|
// (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE
|
|
// BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO
|
|
// NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
|
|
// CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT
|
|
// APPLY TO LICENSEE.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
`define IP_UUID _80fa5e3b79ce4c76a6cd48724ad5bdd2
|
|
`define IP_NAME_CONCAT(a,b) a``b
|
|
`define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID)
|
|
module divider (
|
|
input [15:0] numer,
|
|
input [15:0] denom,
|
|
input clken,
|
|
input clk,
|
|
input reset,
|
|
output [15:0] quotient,
|
|
output [15:0] remain,
|
|
output rfd
|
|
);
|
|
`IP_MODULE_NAME(divider) #(
|
|
.NREPRESENTATION ("UNSIGNED"),
|
|
.WIDTHN (16),
|
|
.WIDTHD (16),
|
|
.DREPRESENTATION ("UNSIGNED"),
|
|
.PIPELINE (1'b0),
|
|
.LATENCY (16)
|
|
) u_divider(
|
|
.numer ( numer ),
|
|
.denom ( denom ),
|
|
.clken ( clken ),
|
|
.clk ( clk ),
|
|
.reset ( reset ),
|
|
.quotient ( quotient ),
|
|
.remain ( remain ),
|
|
.rfd ( rfd )
|
|
);
|
|
|
|
endmodule
|
|
|
|
`timescale 1ns / 1ps
|
|
|
|
module `IP_MODULE_NAME(divider) (
|
|
clk,
|
|
reset,
|
|
numer,
|
|
denom,
|
|
quotient,
|
|
remain,
|
|
rfd,
|
|
clken
|
|
);
|
|
|
|
parameter WIDTHN = 8;
|
|
parameter WIDTHD = 8;
|
|
parameter LATENCY = 8;
|
|
parameter PIPELINE = 1;
|
|
parameter NREPRESENTATION = "UNSIGNED";
|
|
parameter DREPRESENTATION = "UNSIGNED";
|
|
parameter ENABLE_OUTREG = 0;
|
|
|
|
input clk;
|
|
input reset;
|
|
input clken;
|
|
input [(WIDTHN-1):0] numer;
|
|
input [(WIDTHD-1):0] denom;
|
|
//output
|
|
output reg rfd;
|
|
output reg [(WIDTHN-1):0] quotient;
|
|
output reg [(WIDTHD-1):0] remain;
|
|
|
|
wire [WIDTHN-1:0] numer_temp;
|
|
wire [WIDTHD-1:0] denom_temp;
|
|
wire sign_numer;
|
|
wire sign_denom;
|
|
|
|
wire [(WIDTHN-1):0] quotient_copy;
|
|
wire [(WIDTHD-1):0] remain_copy;
|
|
reg sign_quotient[LATENCY:0];
|
|
|
|
genvar i, j;
|
|
// Main operation
|
|
generate begin
|
|
if(NREPRESENTATION == "SIGNED") begin
|
|
assign numer_temp = (numer[(WIDTHN-1)] == 1'b1) ? (~numer + 1) : numer;
|
|
assign sign_numer = (numer[(WIDTHN-1)] == 1'b1) ? 1'b1 : 1'b0;
|
|
end
|
|
else begin
|
|
assign numer_temp = numer;
|
|
assign sign_numer = 1'b0;
|
|
end
|
|
|
|
if(DREPRESENTATION == "SIGNED") begin
|
|
assign denom_temp = (denom[(WIDTHD-1)] == 1'b1) ? (~denom + 1) : denom;
|
|
assign sign_denom = (denom[(WIDTHD-1)] == 1'b1) ? 1'b1 : 1'b0;
|
|
end
|
|
else begin
|
|
assign denom_temp = denom;
|
|
assign sign_denom = 1'b0;
|
|
end
|
|
|
|
always @* begin
|
|
sign_quotient[0] = sign_numer ^ sign_denom;
|
|
end
|
|
|
|
for (i=0; i<LATENCY; i=i+1) begin
|
|
always @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
sign_quotient[i+1] <= 1'b0;
|
|
end
|
|
else if(clken) begin
|
|
sign_quotient[i+1] <= sign_quotient[i];
|
|
end
|
|
end
|
|
end
|
|
|
|
if (PIPELINE) begin : pipeline
|
|
wire [(WIDTHN+1):0] sub[WIDTHN-1:0];
|
|
reg [WIDTHN-1:0] quotient_temp[WIDTHN:0];
|
|
reg [WIDTHN-1:0] remain_temp[WIDTHN:0];
|
|
reg [WIDTHN-1:0] denom_copy[WIDTHN:0];
|
|
|
|
always @* begin
|
|
rfd = 1'b0; //for PIPELINE enable, rfd is not used
|
|
denom_copy[0] = denom_temp;
|
|
remain_temp[0] = {WIDTHN{1'b0}};
|
|
quotient_temp[0] = numer_temp;
|
|
end
|
|
|
|
for (i=0; i<WIDTHN; i=i+1) begin
|
|
assign sub[i] = {remain_temp[i][(WIDTHN-2):0], quotient_temp[i][(WIDTHN-1)]} - denom_copy[i];
|
|
|
|
if (i < LATENCY) begin
|
|
always @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
remain_temp[i+1] <= {WIDTHN{1'b0}};
|
|
quotient_temp[i+1] <= {WIDTHN{1'b0}};
|
|
denom_copy[i+1] <= {WIDTHN{1'b0}};
|
|
end
|
|
else if(clken) begin
|
|
denom_copy[i+1] <= denom_copy[i];
|
|
|
|
if (sub[i][(WIDTHN)] == 0) begin
|
|
remain_temp[i+1] <= sub[i][(WIDTHN-1):0];
|
|
quotient_temp[i+1] <= {quotient_temp[i][(WIDTHN-2):0], 1'b1};
|
|
end
|
|
else begin
|
|
remain_temp[i+1] <= {remain_temp[i][(WIDTHN-2):0], quotient_temp[i][(WIDTHN-1)]};
|
|
quotient_temp[i+1] <= {quotient_temp[i][(WIDTHN-2):0], 1'b0};
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else begin
|
|
always @* begin
|
|
denom_copy[i+1] = denom_copy[i];
|
|
end
|
|
|
|
always @* begin
|
|
if (sub[i][(WIDTHN)] == 0) begin
|
|
remain_temp[i+1] = sub[i][(WIDTHN-1):0];
|
|
end
|
|
else begin
|
|
remain_temp[i+1] = {remain_temp[i][(WIDTHN-2):0], quotient_temp[i][(WIDTHN-1)]};
|
|
end
|
|
end
|
|
|
|
always @* begin
|
|
if (sub[i][(WIDTHN)] == 0) begin
|
|
quotient_temp[i+1] = {quotient_temp[i][(WIDTHN-2):0], 1'b1};
|
|
end
|
|
else begin
|
|
quotient_temp[i+1] = {quotient_temp[i][(WIDTHN-2):0], 1'b0};
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (NREPRESENTATION == "SIGNED" || DREPRESENTATION == "SIGNED") begin
|
|
assign quotient_copy = sign_quotient[LATENCY] ? (~quotient_temp[WIDTHN] + 1) : quotient_temp[WIDTHN];
|
|
end
|
|
else begin
|
|
assign quotient_copy = quotient_temp[WIDTHN];
|
|
end
|
|
|
|
assign remain_copy = remain_temp[WIDTHN];
|
|
end
|
|
else begin : non_pipeline
|
|
localparam COMBI_STAGE = WIDTHN - LATENCY;
|
|
|
|
wire [(WIDTHN-1):0] denom_sub;
|
|
reg [WIDTHN-1:0] denom_reg;
|
|
reg [(WIDTHN-1):0] quotient_reg;
|
|
reg [(WIDTHN-1):0] remain_reg;
|
|
wire [(WIDTHN+1):0] sub;
|
|
reg [(WIDTHN-1):0] quotient_combi[COMBI_STAGE:0];
|
|
reg [WIDTHN-1:0] remain_combi[COMBI_STAGE:0];
|
|
wire [(WIDTHN+1):0] sub_combi[COMBI_STAGE:0];
|
|
|
|
reg clken_IP;
|
|
|
|
assign denom_sub = {{(WIDTHN-WIDTHD){1'b0}},denom_temp};
|
|
|
|
always @(posedge clk,posedge reset) begin
|
|
if(reset) begin
|
|
clken_IP <= 1'b0;
|
|
end
|
|
else begin
|
|
clken_IP <= clken;
|
|
end
|
|
end
|
|
|
|
if(LATENCY > 0) begin
|
|
reg [LATENCY-1:0] ready;
|
|
|
|
assign sub = (ready[0] || ~clken_IP) ? ({{(WIDTHN-2){1'b0}}, numer_temp[(WIDTHN-1)]} - denom_sub) : ({remain_reg[(WIDTHN-2):0], quotient_reg[(WIDTHN-1)]} - denom_reg);
|
|
|
|
always @(posedge clk,posedge reset) begin
|
|
if(reset) begin
|
|
ready <= {LATENCY{1'b0}};
|
|
end
|
|
else if(clken) begin
|
|
if(ready[0] || ~clken_IP) begin
|
|
ready <= {1'b1, {LATENCY-1{1'b0}}};
|
|
end
|
|
else begin
|
|
ready <= {1'b0, ready[LATENCY-1:1]};
|
|
end
|
|
end
|
|
else begin
|
|
ready <= {LATENCY{1'b0}};
|
|
end
|
|
end
|
|
|
|
always @(posedge clk,posedge reset) begin
|
|
if(reset) begin
|
|
remain_reg <= {WIDTHN{1'b0}};
|
|
quotient_reg <= {WIDTHN{1'b0}};
|
|
denom_reg <= {WIDTHN{1'b0}};
|
|
end
|
|
else if(clken) begin
|
|
if(ready[0] || ~clken_IP) begin
|
|
denom_reg <= denom_temp;
|
|
if (sub[(WIDTHN)] == 0) begin
|
|
remain_reg <= sub[(WIDTHN-1):0];
|
|
quotient_reg <= {numer_temp[(WIDTHN-2):0], 1'b1};
|
|
end
|
|
else begin
|
|
remain_reg <= {{(WIDTHN-2){1'b0}}, numer_temp[(WIDTHN-1)]};
|
|
quotient_reg <= {numer_temp[(WIDTHN-2):0], 1'b0};
|
|
end
|
|
end
|
|
else begin
|
|
if (sub[(WIDTHN)] == 0) begin
|
|
remain_reg <= sub[(WIDTHN-1):0];
|
|
quotient_reg <= {quotient_reg[(WIDTHN-2):0], 1'b1};
|
|
end
|
|
else begin
|
|
remain_reg <= {remain_reg[(WIDTHN-2):0], quotient_reg[(WIDTHN-1)]};
|
|
quotient_reg <= {quotient_reg[(WIDTHN-2):0], 1'b0};
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (ENABLE_OUTREG) begin
|
|
always @(posedge clk,posedge reset) begin
|
|
if (reset) begin
|
|
rfd <= 1'b0;
|
|
end
|
|
else begin
|
|
rfd <= ready[0];
|
|
end
|
|
end
|
|
end
|
|
else begin
|
|
always @* begin
|
|
rfd = ready[0];
|
|
end
|
|
end
|
|
|
|
always @* begin
|
|
quotient_combi[0] = quotient_reg;
|
|
remain_combi[0] = remain_reg;
|
|
end
|
|
|
|
for (i=0; i<COMBI_STAGE; i=i+1) begin
|
|
assign sub_combi[i] = {remain_combi[i][(WIDTHN-2):0], quotient_combi[i][(WIDTHN-1)]} - denom_reg;
|
|
end
|
|
end
|
|
else begin
|
|
always @* begin
|
|
rfd = 1'b1;
|
|
end
|
|
|
|
always @* begin
|
|
quotient_combi[0] = numer_temp;
|
|
remain_combi[0] = {WIDTHN{1'b0}};
|
|
end
|
|
for (i=0; i<COMBI_STAGE; i=i+1) begin
|
|
assign sub_combi[i] = {remain_combi[i][(WIDTHN-2):0], quotient_combi[i][(WIDTHN-1)]} - denom_sub;
|
|
end
|
|
end
|
|
|
|
for (i=0; i<COMBI_STAGE; i=i+1) begin
|
|
always @* begin
|
|
if(sub_combi[i][(WIDTHN)] == 0) begin
|
|
remain_combi [i+1] = sub_combi[i][(WIDTHN-1):0];
|
|
quotient_combi [i+1] = {quotient_combi[i][(WIDTHN-2):0], 1'b1};
|
|
end
|
|
else begin
|
|
remain_combi[i+1] = {remain_combi[i][(WIDTHN-2):0], quotient_combi[i][(WIDTHN-1)]};
|
|
quotient_combi[i+1] = {quotient_combi[i][(WIDTHN-2):0], 1'b0};
|
|
end
|
|
end
|
|
end
|
|
|
|
if(NREPRESENTATION == "SIGNED" || DREPRESENTATION == "SIGNED") begin
|
|
assign quotient_copy = sign_quotient[LATENCY] ? (~quotient_combi[COMBI_STAGE] + 1): quotient_combi[COMBI_STAGE];//
|
|
end
|
|
else begin
|
|
assign quotient_copy = quotient_combi[COMBI_STAGE];
|
|
end
|
|
|
|
assign remain_copy = remain_combi[COMBI_STAGE];
|
|
end
|
|
|
|
if (ENABLE_OUTREG) begin
|
|
always @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
quotient <= {WIDTHN{1'b0}};
|
|
remain <= {WIDTHD{1'b0}};
|
|
end
|
|
else begin
|
|
quotient <= quotient_copy;
|
|
remain <= remain_copy;
|
|
end
|
|
end
|
|
end
|
|
else begin
|
|
always @* begin
|
|
quotient = quotient_copy;
|
|
remain = remain_copy;
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
endmodule
|
|
`undef IP_UUID
|
|
`undef IP_NAME_CONCAT
|
|
`undef IP_MODULE_NAME
|