https://www.synopsys.com/dw/buildingblock.php
https://max.book118.com/html/2018/0204/151848438.shtm
https://caxapa.ru/thumbs/405687/dw_qrg.pdf
无符号操作图:
有符号操作图:
配置参数介绍:
参数名 | 默认值 | 参考值 | 功能 |
---|---|---|---|
a_width | None | ≥ 2 | 除数的位宽 |
b_width | None | ≥ 2 & ≤ a_width | 被除数的位宽 |
tc_mode | 0 | 0 or 1 | 是否有符号 |
rem_mode | 1 | 0 or 1 | 余数选择 模或余数 |
num_stages | 2 | ≥ 2 | 流水线级数 |
stall_mode | 1 | 0 or 1 | 暂停模式 |
rst_mode | 1 | 0 to 2 | 复位模式 |
op_iso_mode | 1 | 0 to 2 | 操作隔离模式 |
英文原文
Dw_div_pipe divides the operands a by b to produce a quotient and a remainder, if selected through aparameter, with a latency of num_stages-1 clock (clk) cycles.
The parameter tc_mode determines whetherthe input and output data is interpreted as unsigned (tc_mode=0) or signed (tc_mode=1) numbers.
Automatic pipeline retiming ensures optimal placement of pipeline registers within the divider to achievemaximum throughput.
The pipeline can be stalled by setting the load enable signal en low(stall_mode=1).
The pipeline registers can either have no reset (rst_mode=0) or an asychronous (rst_mode=1) or synchronous reset (rst_mode=2) connected to the reset signal rst_n.
Operand lsolation Mode
lf "stall_mode' is '0' , this parameter is ignored and no isolation is applied. o Follow intent defined by Power Compiler user setting
1 = 'none'
2 = 'and"3 'or'
4 = preferred isolation style : 'and
Note: See the DesignWare Building Block IP Low-Power Overview for detailson how to apply operand isolation.
Dw_div_pipe 将操作数a除以b得到商和余数,其延迟为num_stages-1个模块时钟周期。流水线重定时保证流水线寄存器在除法器的最佳位置,以实现最大的吞吐量。
参数 | 功能 |
---|---|
tc_mode | 确定输入和输出数据是被解释为无符号数(tc_mode=0)还是有符号数(tc_mode=1)。 |
stall_mode | stall_mode=1时,可以通过将“en”信号拉低,来暂停流水线。 |
rst_mode | 流水线寄存器可以没有重置(rst_mode=0)或异步(rst_mode=1)或同步复位(rst_mode=2)连接到复位信号rst_n。 |
操作数隔离模式
如果“stall_mode”为“0”,则忽略此参数并且不应用隔离。o遵循Power Compiler用户设置定义的意图
1 =“没有”
2 = 'and '
3 = 'or'
4 = 首选隔离方式: 'and'
注意:有关如何应用操作数隔离的详细信息,请参阅DesignWare构建块IP低功耗概述。
对于正值模数和余数之间没有区别,对于负数模数和余数之间存在差异。
例如:
-21/4模数是3,因为 -21 + 4 x 6是 3。
但是-21除以4商-5余数为-1 。
DW_div_pipe
////////////////////////////////////////////////////////////////////////////////
//
// This confidential and proprietary software may be used only
// as authorized by a licensing agreement from Synopsys Inc.
// In the event of publication, the following notice is applicable:
//
// (C) COPYRIGHT 2000 - 2014 SYNOPSYS INC.
// ALL RIGHTS RESERVED
//
// The entire notice above must be reproduced on all authorized
// copies.
//
// AUTHOR: Rajeev Huralikoppi Feb 15, 2002
//
// VERSION: Verilog Simulation Architecture
//
// DesignWare_version: 289c69a9
// DesignWare_release: I-2013.12-DWBB_201312.5
//
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// ABSTRACT: An n stage pipelined Divider Simulation model
//
// Parameters Valid Values Description
// ========== ========= ===========
// a_width >= 1 default: none
// Word length of a
//
// b_width >= 1 default: none
// Word length of b
//
// tc_mode 0 or 1 default: 0
// Two's complement control:
// 0 => inputs/outputs unsigned
// 1 => inputs/outputs two's complement
//
// rem_mode 0 or 1 default: 1
// Remainder output control:
// 0 => remainder output is VHDL modulus
// 1 => remainder output is remainder
//
// num_stages >= 2 default: 2
// Number of pipelined stages
//
// stall_mode 0 or 1 default: 1
// Stall mode
// 0 => non-stallable
// 1 => stallable
//
// rst_mode 0 to 2 default: 1
// Reset mode
// 0 => no reset
// 1 => asynchronous reset
// 2 => synchronous reset
//
// op_iso_mode 0 to 4 default: 0
// Type of operand isolation
// If 'stall_mode' is '0', this parameter is ignored and no isolation is applied
// 0 => Follow intent defined by Power Compiler user setting
// 1 => no operand isolation
// 2 => 'and' gate operand isolaton
// 3 => 'or' gate operand isolation
// 4 => preferred isolation style: 'or'
//
//
// Input Ports Size Description
// =========== ==== ============
// clk 1 Clock
// rst_n 1 Reset, active low
// en 1 Register enable, active high
// a a_width Divisor
// b b_width Dividend
//
// Output Ports Size Description
// ============ ==== ============
// quotient a_width quotient (a/b)
// remainder b_width remainder
// divide_by_0 1 divide by zero flag
//
//
// MODIFIED:
// RJK 05/28/13 Updated documentation in comments to properly
// describe the "en" input (STAR 9000627580)
//
// DLL 01/28/08 Enhanced abstract and added "op_iso_mode" parameter
// and related code.
//
// DLL 11/10/05 Changed legality checking of 'num_stages'
// parameter along with its abstract "Valid Values"
//
// RJK 2/5/03 Fixed port size mismatches for output
// ports, quotient & divisor (STAR 159440)
//
//-----------------------------------------------------------------------------
module DW_div_pipe (clk,rst_n,en,a,b,quotient,remainder,divide_by_0);
parameter a_width = 2;
parameter b_width = 2;
parameter tc_mode = 0;
parameter rem_mode = 1;
parameter num_stages = 2;
parameter stall_mode = 1;
parameter rst_mode = 1;
parameter op_iso_mode = 0;
input clk;
input rst_n;
input [a_width-1 : 0] a;
input [b_width-1 : 0] b;
input en;
output [a_width-1 : 0] quotient;
output [b_width-1 : 0] remainder;
output divide_by_0;
wire a_rst_n;
reg [a_width-1 : 0] a_reg[0 : num_stages-1];
reg [b_width-1 : 0] b_reg[0 : num_stages-1];
// synopsys translate_off
//---------------------------------------------------------------------------
// Behavioral model
//---------------------------------------------------------------------------
assign a_rst_n = (rst_mode == 1)? rst_n : 1'b1;
always @(posedge clk or negedge a_rst_n)
begin: pipe_reg_PROC
integer i,j;
reg [a_width-1 : 0] a_var[0 : num_stages-1];
reg [b_width-1 : 0] b_var[0 : num_stages-1];
a_var[0] = a;
b_var[0] = b;
if (rst_mode != 0 & rst_n === 1'b0) begin
for (i= 1; i < num_stages; i=i+1) begin
a_var[i] = {a_width{1'b0}};
b_var[i] = {b_width{1'b0}};
end // for (i= 1; i < num_stages-1; i++)
end // if (rst_mode != 0 & rst_n === 1'b0)
else if (rst_mode == 0 || rst_n === 1'b1) begin
// pipeline disbled
if (stall_mode != 0 && en === 1'b0) begin
for (i= 1; i < num_stages; i=i+1) begin
a_var[num_stages-i] = a_var[num_stages-i];
b_var[num_stages-i] = b_var[num_stages-i];
end // for (i= 1; i < num_stages-1; i++)
end // if (stall_mode /= 0 || en === 1'b0)
else if (stall_mode == 0 || en === 1'b1) begin
// pipeline enabled
for (i= 1; i < num_stages; i=i+1) begin
a_var[num_stages-i] = a_var[num_stages-i-1]; //Changed By Me
//a_var[i] = a_var[i-1];
b_var[num_stages-i] = b_var[num_stages-i-1];
//b_var[i] = b_var[i-1];
end // for (i= 1; i < num_stages-1; i++)
end // if (stall_mode == 0 || en === 1'b1)
else begin // X processing on en
for (i= 1; i < num_stages; i=i+1) begin
a_var[i] = {a_width{1'bx}};
b_var[i] = {b_width{1'bx}};
end // for (i= 1; i < num_stages-1; i++)
end // else: !if(stall_mode == 0 || en === 1'b1)
end // if (rst_mode == 0 || rst_n === 1'b1)
else begin
for (i= 1; i < num_stages; i=i+1) begin
a_var[i] = {a_width{1'bx}};
b_var[i] = {b_width{1'bx}};
end // for (i= 1; i < num_stages-1; i++)
end // else: !if(rst_n === 1'b1)
for(i= 1; i < num_stages; i=i+1) begin
a_reg[i] <= a_var[i];
b_reg[i] <= b_var[i];
end
end // block: pipe_reg_PROC
DW_div #(a_width, b_width, tc_mode, rem_mode)
U1 (.a(a_reg[num_stages-1]),
.b(b_reg[num_stages-1]),
.quotient(quotient),
.remainder(remainder),
.divide_by_0(divide_by_0));
//---------------------------------------------------------------------------
// Parameter legality check and initializations
//---------------------------------------------------------------------------
initial begin : parameter_check
integer param_err_flg;
param_err_flg = 0;
if (a_width < 1) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter a_width (lower bound: 1)",
a_width );
end
if (b_width < 1) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter b_width (lower bound: 1)",
b_width );
end
if ( (tc_mode < 0) || (tc_mode > 1) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter tc_mode (legal range: 0 to 1)",
tc_mode );
end
if ( (rem_mode < 0) || (rem_mode > 1) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter rem_mode (legal range: 0 to 1)",
rem_mode );
end
if (num_stages < 2) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter num_stages (lower bound: 2)",
num_stages );
end
if ( (stall_mode < 0) || (stall_mode > 1) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter stall_mode (legal range: 0 to 1)",
stall_mode );
end
if ( (rst_mode < 0) || (rst_mode > 2) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter rst_mode (legal range: 0 to 2)",
rst_mode );
end
if ( (op_iso_mode < 0) || (op_iso_mode > 4) ) begin
param_err_flg = 1;
$display(
"ERROR: %m :\n Invalid value (%d) for parameter op_iso_mode (legal range: 0 to 4)",
op_iso_mode );
end
if ( param_err_flg == 1) begin
$display(
"%m :\n Simulation aborted due to invalid parameter value(s)");
$finish;
end
end // parameter_check
//---------------------------------------------------------------------------
// Report unknown clock inputs
//---------------------------------------------------------------------------
always @ (clk) begin : clk_monitor
if ( (clk !== 1'b0) && (clk !== 1'b1) && ($time > 0) )
$display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk input.",
$time, clk );
end // clk_monitor
// synopsys translate_on
endmodule //