📄 220model.v
字号:
for (i = 0; i <= lpm_pipeline; i = i + 1)
begin
tmp_aeb2[i] = 'b0;
tmp_agb2[i] = 'b0;
tmp_alb2[i] = 'b0;
tmp_aleb2[i] = 'b0;
tmp_aneb2[i] = 'b0;
tmp_ageb2[i] = 'b0;
end
else
begin
tmp_aeb2[lpm_pipeline] = (dataa == datab);
tmp_aneb2[lpm_pipeline] = (dataa != datab);
if ((lpm_representation == "SIGNED") &&
(dataa[lpm_width-1] ^ datab[lpm_width-1]) == 1)
begin
// create latency
tmp_alb2[lpm_pipeline] = (dataa > datab);
tmp_agb2[lpm_pipeline] = (dataa < datab);
tmp_aleb2[lpm_pipeline] = (dataa >= datab);
tmp_ageb2[lpm_pipeline] = (dataa <= datab);
end
else
begin
// create latency
tmp_alb2[lpm_pipeline] = (dataa < datab);
tmp_agb2[lpm_pipeline] = (dataa > datab);
tmp_aleb2[lpm_pipeline] = (dataa <= datab);
tmp_ageb2[lpm_pipeline] = (dataa >= datab);
end
end
end
// pipelining process
always @(posedge i_clock)
begin
if ((!i_aclr) && (i_clken == 1))
for (i = 0; i < lpm_pipeline; i = i + 1)
begin
tmp_alb2[i] <= tmp_alb2[i+1];
tmp_aeb2[i] <= tmp_aeb2[i+1];
tmp_agb2[i] <= tmp_agb2[i+1];
tmp_aleb2[i] <= tmp_aleb2[i+1];
tmp_aneb2[i] <= tmp_aneb2[i+1];
tmp_ageb2[i] <= tmp_ageb2[i+1];
end
end
// CONTINOUS ASSIGNMENT
assign alb = tmp_alb2[0];
assign aeb = tmp_aeb2[0];
assign agb = tmp_agb2[0];
assign aleb = tmp_aleb2[0];
assign aneb = tmp_aneb2[0];
assign ageb = tmp_ageb2[0];
endmodule // lpm_compare
//START_MODULE_NAME------------------------------------------------------------
//
// Module Name : lpm_mult
//
// Description : Parameterized multiplier megafunction.
//
// Limitation : n/a
//
// Results expected: dataa[] * datab[] + sum[].
//
//END_MODULE_NAME--------------------------------------------------------------
// BEGINNING OF MODULE
`timescale 1 ps / 1 ps
// MODULE DECLARATION
module lpm_mult (
dataa, // Multiplicand. (Required)
datab, // Multiplier. (Required)
sum, // Partial sum.
aclr, // Asynchronous clear for pipelined usage.
clock, // Clock for pipelined usage.
clken, // Clock enable for pipelined usage.
result // result = dataa[] * datab[] + sum. The product LSB is aligned with the sum LSB.
);
// GLOBAL PARAMETER DECLARATION
parameter lpm_widtha = 1; // Width of the dataa[] port. (Required)
parameter lpm_widthb = 1; // Width of the datab[] port. (Required)
parameter lpm_widthp = 1; // Width of the result[] port. (Required)
parameter lpm_widths = 1; // Width of the sum[] port. (Required)
parameter lpm_representation = "UNSIGNED"; // Type of multiplication performed
parameter lpm_pipeline = 0; // Number of clock cycles of latency
parameter lpm_type = "lpm_mult";
parameter lpm_hint = "UNUSED";
// INPUT PORT DECLARATION
input [lpm_widtha-1:0] dataa;
input [lpm_widthb-1:0] datab;
input [lpm_widths-1:0] sum;
input aclr;
input clock;
input clken;
// OUTPUT PORT DECLARATION
output [lpm_widthp-1:0] result;
// INTERNAL REGISTER/SIGNAL DECLARATION
reg [lpm_widthp-1:0] resulttmp [lpm_pipeline:0];
reg [lpm_widthp-1:0] i_prod;
reg [lpm_widthp-1:0] t_p;
reg [lpm_widths-1:0] i_prod_s;
reg [lpm_widths-1:0] t_s;
reg [lpm_widtha+lpm_widthb-1:0] i_prod_ab;
reg [lpm_widtha-1:0] t_a;
reg [lpm_widthb-1:0] t_b;
reg sign_ab;
reg sign_s;
// LOCAL INTEGER DECLARATION
integer i;
// INTERNAL TRI DECLARATION
tri0 aclr;
tri0 clock;
tri1 clken;
buf (i_aclr, aclr);
buf (i_clock, clock);
buf (i_clken, clken);
// INITIAL CONSTRUCT BLOCK
initial
begin
// check if lpm_widtha > 0
if (lpm_widtha <= 0)
begin
$display("Error! lpm_widtha must be greater than 0.\n");
$finish;
end
// check if lpm_widthb > 0
if (lpm_widthb <= 0)
begin
$display("Error! lpm_widthb must be greater than 0.\n");
$finish;
end
// check if lpm_widthp > 0
if (lpm_widthp <= 0)
begin
$display("Error! lpm_widthp must be greater than 0.\n");
$finish;
end
// check if lpm_widthp > 0
if (lpm_widths <= 0)
begin
$display("Error! lpm_widths must be greater than 0.\n");
$finish;
end
// check for valid lpm_rep value
if ((lpm_representation != "SIGNED") && (lpm_representation != "UNSIGNED"))
begin
$display("Error! lpm_representation value must be \"SIGNED\" or \"UNSIGNED\".", $time);
$finish;
end
end
// ALWAYS CONSTRUCT BLOCK
always @(dataa or datab or sum or i_aclr)
begin
if (i_aclr) // clear the pipeline for result to 0
for (i = 0; i <= lpm_pipeline; i = i + 1)
resulttmp[i] = 'b0;
else
begin
t_a = dataa;
t_b = datab;
t_s = sum;
sign_ab = 0;
sign_s = 0;
// if inputs are sign number
if (lpm_representation == "SIGNED")
begin
sign_ab = dataa[lpm_widtha-1] ^ datab[lpm_widthb-1];
sign_s = sum[lpm_widths-1];
// if negative number, represent them as 2 compliment number.
if (dataa[lpm_widtha-1] == 1)
t_a = (~dataa) + 1;
if (datab[lpm_widthb-1] == 1)
t_b = (~datab) + 1;
if (sum[lpm_widths-1] == 1)
t_s = (~sum) + 1;
end
// if sum port is not used
if (sum === {lpm_widths{1'bz}})
begin
t_s = 0;
sign_s = 0;
end
if (sign_ab == sign_s)
begin
i_prod = (t_a * t_b) + t_s;
i_prod_s = (t_a * t_b) + t_s;
i_prod_ab = (t_a * t_b) + t_s;
end
else
begin
i_prod = (t_a * t_b) - t_s;
i_prod_s = (t_a * t_b) - t_s;
i_prod_ab = (t_a * t_b) - t_s;
end
// if dataa[] * datab[] produces negative number, compliment the result
if (sign_ab)
begin
i_prod = (~i_prod) + 1;
i_prod_s = (~i_prod_s) + 1;
i_prod_ab = (~i_prod_ab) + 1;
end
if ((lpm_widthp < lpm_widths) || (lpm_widthp < lpm_widtha+lpm_widthb))
for (i = 0; i < lpm_widthp; i = i + 1)
i_prod[lpm_widthp-1-i] = (lpm_widths > lpm_widtha+lpm_widthb)
? i_prod_s[lpm_widths-1-i]
: i_prod_ab[lpm_widtha+lpm_widthb-1-i];
// pipelining the result
resulttmp[lpm_pipeline] = i_prod;
end
end
always @(posedge i_clock)
begin
if (!i_aclr && i_clken == 1)
for (i = 0; i < lpm_pipeline; i = i + 1)
resulttmp[i] <= resulttmp[i+1];
end
// CONTINOUS ASSIGNMENT
assign result = resulttmp[0];
endmodule // lpm_mult
// END OF MODULE
//START_MODULE_NAME------------------------------------------------------------
//
// Module Name : lpm_divide
//
// Description : Parameterized divider megafunction. This function performs a
// divide operation such that denom * quotient + remain = numer
// The function allows for all combinations of signed(two's
// complement) and unsigned inputs. If any of the inputs is
// signed, the output is signed. Otherwise the output is unsigned.
// The function also allows the remainder to be specified as
// always positive (in which case remain >= 0); otherwise remain
// is zero or the same sign as the numerator
// (this parameter is ignored in the case of purely unsigned
// division). Finally the function is also pipelinable.
//
// Limitation : n/a
//
// Results expected: Return quotient and remainder.
//
//END_MODULE_NAME--------------------------------------------------------------
// BEGINNING OF MODULE
`timescale 1 ps / 1 ps
// MODULE DECLARATION
module lpm_divide (
numer, // The numerator (Required)
denom, // The denominator (Required)
clock, // Clock input for pipelined usage
aclr, // Asynchronous clear signal
clken, // Clock enable for pipelined usage.
quotient, // Quotient (Required)
remain // Remainder (Required)
);
// GLOBAL PARAMETER DECLARATION
parameter lpm_widthn = 1; // Width of the numer[] and quotient[] port. (Required)
parameter lpm_widthd = 1; // Width of the denom[] and remain[] port. (Required)
parameter lpm_nrepresentation = "UNSIGNED"; // The representation of numer
parameter lpm_drepresentation = "UNSIGNED"; // The representation of denom
parameter lpm_pipeline = 0; // Number of Clock cycles of latency
parameter lpm_type = "lpm_divide";
parameter lpm_hint = "LPM_REMAINDERPOSITIVE=TRUE";
// INPUT PORT DECLARATION
input [lpm_widthn-1:0] numer;
input [lpm_widthd-1:0] denom;
input clock;
input aclr;
input clken;
// OUTPUT PORT DECLARATION
output [lpm_widthn-1:0] quotient;
output [lpm_widthd-1:0] remain;
// INTERNAL REGISTER/SIGNAL DECLARATION
reg [lpm_widthn-1:0] tmp_quotient [lpm_pipeline:0];
reg [lpm_widthd-1:0] tmp_remain [lpm_pipeline:0];
reg [lpm_widthn-1:0] ONES, ZEROS, UNKNOWN, HiZ;
reg [lpm_widthd-1:0] DZEROS, DUNKNOWN;
reg [lpm_widthn-1:0] NUNKNOWN;
reg [lpm_widthd-1:0] RZEROS;
reg [lpm_widthn-1:0] not_numer, int_numer;
reg [lpm_widthd-1:0] not_denom, int_denom;
reg [lpm_widthn-1:0] t_numer, t_q;
reg [lpm_widthd-1:0] t_denom, t_r;
reg sign_q, sign_r, sign_n, sign_d;
reg [2:0] tsig;
reg [8*5:1] lpm_remainderpositive;
// LOCAL INTEGER DECLARATION
integer i;
integer rsig;
// INTERNAL TRI DECLARATION
tri0 aclr;
tri0 clock;
tri1 clken;
buf (i_aclr, aclr);
buf (i_clock, clock);
buf (i_clken, clken);
// COMPONENT INSTANTIATIONS
LPM_HINT_EVALUATION eva();
// INITIAL CONSTRUCT BLOCK
initial
begin
// check if lpm_widthn > 0
if (lpm_widthn <= 0)
begin
$display("Error! LPM_WIDTHN must be greater than 0.\n");
$finish;
end
// check if lpm_widthd > 0
if (lpm_widthd <= 0)
begin
$display("Error! LPM_WIDTHD must be greater than 0.\n");
$finish;
end
// check for valid lpm_nrepresentation value
if ((lpm_nrepresentation != "SIGNED") && (lpm_nrepresentation != "UNSIGNED"))
begin
$display("Error! LPM_NREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
$finish;
end
// check for valid lpm_drepresentation value
if ((lpm_drepresentation != "SIGNED") && (lpm_drepresentation != "UNSIGNED"))
begin
$display("Error! LPM_DREPRESENTATION value must be \"SIGNED\" or \"UNSIGNED\".");
$finish;
end
// check for valid lpm_remainderpositive value
lpm_remainderpositive = eva.GET_PARAMETER_VALUE(lpm_hint, "LPM_REMAINDERPOSITIVE");
if ((lpm_remainderpositive == "TRUE") &&
(lpm_remainderpositive == "FALSE"))
begin
$display("Error! LPM_REMAINDERPOSITIVE value must be \"TRUE\" or \"FALSE\".");
$finish;
end
for (i=0; i < lpm_widthn; i=i+1)
begin
ONES[i] = 1'b1;
ZEROS[i] = 1'b0;
UNKNOWN[i] = 1'bx;
HiZ[i] = 1'bz;
end
for (i=0; i < lpm_widthd; i=i+1)
DUNKNOWN[i] = 1'bx;
for (i=0; i < lpm_widthn; i=i+1)
NUNKNOWN[i] = 1'bx;
for (i=0; i < lpm_widthd; i=i+1)
RZEROS[i] = 1'b0;
end
// ALWAYS CONSTRUCT BLOCK
always @(numer or denom or i_aclr)
begin
if (i_aclr)
begin
for (i = 0; i <= lpm_pipeline; i = i + 1)
tmp_quotient[i] = ZEROS;
tmp_remain[i] = RZEROS;
end
else
begin
sign_q = 0;
sign_r = 0;
sign_n = 0;
sign_d = 0;
t_numer = numer;
t_denom = denom;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -