用verilog编写的32位超前进位加法器代码
verilog 运算 -回复

verilog 运算-回复Verilog运算(Verilog Operators)引言:Verilog是一种硬件描述语言(HDL),广泛用于数字电子系统的设计和仿真。
在Verilog中,运算是非常重要的,它们用于控制逻辑、数据处理和信号处理等方面。
本文将为大家介绍Verilog中的不同类型运算符及其使用方法。
一、算术运算符在Verilog中,算术运算符用于执行基本的加减乘除操作。
下面是Verilog中使用的常用算术运算符:1. 加法运算符:+用于对两个操作数执行加法操作。
例如,在下面的代码段中,两个32位输入变量a和b将相加,并将结果存储在32位输出变量sum中。
module adder(input [31:0] a, input [31:0] b, output [31:0] sum);assign sum = a + b;endmodule2. 减法运算符:-这个运算符用于执行两个操作数的减法操作。
在下面的代码段中,我们从32位输入变量a中减去32位输入变量b,并将结果存储在32位输出变量diff中。
module subtractor(input [31:0] a, input [31:0] b, output [31:0] diff);assign diff = a - b;endmodule3. 乘法运算符:*乘法运算符用于执行两个操作数的乘法操作。
以下代码段演示了如何将32位输入变量a和b相乘,并将结果存储在64位输出变量product 中。
module multiplier(input [31:0] a, input [31:0] b, output [63:0] product);assign product = a * b;endmodule4. 除法运算符:/除法运算符用于执行两个操作数的除法操作。
在下面的代码段中,我们将32位输入变量a除以32位输入变量b,并将结果存储在32位输出变量quotient中。
基于Verilog HDL的32位分频计数器的设计

分频计数器的基本原理
• 选择合适频率的晶振,然后对其分频,得到 系统需要的时钟频率,再对这一频率时钟进行计 数据。一般的计数器都有输入时钟信号,这里以 晶振的输出时钟作为分频计数据器的输入时钟 CLK。复位信号对各信号进行复位。片选信号用 于选通芯片,以备读写计数值。写信号用于写计 数初始值。读信号用于读取计数值。地址信号 ADDR决定读写计数值的高位还是低位。CLKl为 分频输出的时钟信号。c为输出的进位信号。 DATA为双向数据信号+当系统为分频计数器写 入初始值时是输入,当系统读取计数值时是输出。
基于Verilog HDL的32位分频计 数器的设计
微电子 高翔
Verilog HDL的优点
• Verilog HDL是一种通用的硬件描述语言,易 • 学易用
• Verilog HDL允许在同一个电路模型内进行不 • 同抽象层次的描述
• Verilog HDL 绝大多数流行的综合工具都支持
• 所有的制造厂商都提供用于Verilog HDL综合 • 之后的逻辑仿真的元件库
原理图
实现功能综合
程序仿真
总结
• 首先本文介绍了硬件描述语言的发展状况,并对国内发展 提出了建议,然后对本
• 文要用的硬件语言VerilogHDL进行了详细介绍,并对仿真 所用的软件进行了介
•
绍。
• 其次介绍了32位分频器计数器的原理,并介绍了其它的 分频器,讨论了优缺点,
• 并且详细介绍了本文所用的分频计数器的原理和介绍、分 析。
HDL语言的发展。基于Verilog HDL的优越性,IEEE于
32超前进位加法器

文档编号:GX_HW_0001文档分类:硬件技术文档访问权限:公开32位超前进位加法器总体设计方案Version 1.1版本信息版本日期描述作者V1.1 2011-10-07 采用超前进位链实现郭新32位超前进位加法器目录目录 (3)1.概述 (4)2.总体描述 (4)2.1.功能描述 (4)2.2.顶层框图 (4)2.3.引脚描述 (4)3.模块划分 (5)3.1 概述(叙述一下划分的几个大的模块) (5)3.2模块A (6)3.2.1功能定义 (6)3.2.2信号描述 (6)3.2.3 详细设计 (6)3.3模块B (7)3.3.1功能定义 (7)3.3.2信号描述 (7)3.3.3 详细设计 (7)3.4模块C (8)3.4.1功能定义 (8)3.4.2信号描述 (8)3.4.3 详细设计 (8)3.5模块D (9)3.5.1功能定义 (9)3.5.2信号描述 (9)3.5.3 详细设计 (9)4.验证方案 (10)5.设计开发环境 (10)6.源代码 (10)6.1顶层模块 (10)6.2模块A (12)6.3模块B (12)6.4模块C (13)6.5模块D (14)6.6测试模块 (15)6.7测试波形 (16)1.概述利用各位数据和最低位进位同时输入,各位之间的进位信号与和就能同时产生,实现超前进位加法器,这种加法器运算速度显著提高,但电路复杂程度也急剧增加。
2.总体描述2.1.功能描述超前进位逻辑从输入中读入进位、传播值和生成值等信息,计算每一位的进位值。
该逻辑产生进位值和加值,加值只是输入的异或。
进位值用4位超前进位块的三级树来计算。
2.2.顶层框图32bit_claa(31:0)b(31:0)cins(31:0)cout图2.1加法器顶层框图2.3.引脚描述表2.1 顶层接口信号描述名称输入/输出功能描述a 输入32位输入b 输入32位输入cin 输入低级进位输入s 输入32位输出cout 输入进位输出3.模块划分(各个模块中不涉及时序,时序分析略去。
32位计数器verilog代码

32位计数器verilog代码以下是一个简单的 32 位计数器的 Verilog 代码示例。
该计数器每个时钟周期递增一次,当计数达到最大值时,重新从零开始。
module Counter(
input wire clk, // 时钟信号
input wire reset, // 复位信号
output reg [31:0] count // 32 位计数器
);
always @(posedge clk or posedge reset) begin
if (reset) begin
// 复位时,计数器清零
count <= 32'b0;
end else begin
// 在每个上升沿时递增计数器
count <= count + 1;
end
end
endmodule
在这个示例中,Counter 模块有一个时钟输入 clk 和一个复位输入 reset,以及一个 32 位的计数器输出 count。
计数器在每个时
1/ 2
钟上升沿或复位信号的上升沿触发。
当复位信号为高电平时,计数器被清零,否则,计数器递增。
请注意,这只是一个基本的示例。
实际应用中,你可能需要根据具体的需求添加一些功能,如计数器的最大值、启用/禁用等。
2/ 2。
上海大学verilog设计32位浮点加法器设计

32位浮点加法器设计摘要:浮点数具有数值范围大,表示格式不受限制的特点,因此浮点数的应用是非常广泛的。
浮点数加法运算比较复杂,算法很多,但是为了提高运算速度,大部分均是基于流水线的设计结构。
本文介绍了基于IEE754标准的用Verilog 语言设计的32位浮点加法器,能够实现32位浮点数的加法运算。
虽然未采用流水线的设计结构但是仍然对流水线结构做了比较详细的介绍。
关键字:浮点数,流水线,32位浮点数加法运算,Verilog 语言设计32-bit floating point adder designCao Chi,Shen Jia- qi,Zheng Yun-jia(School of Mechatronic Engineering and Automation, Shanghai University, Shanghai ,China ) Abstract://沈佳琪搞定Key words :float; Assembly line; 32-bit floating-point adder 浮点数的应用非常广泛,无论是在计算机还是微处理器中都离不开浮点数。
但是浮点数的加法运算规则比较复杂不易理解掌握,而且按照传统的运算方法,运算速度较慢。
因此,浮点加法器的设计采用了流水线的设计方法。
32位浮点数运算的摄入处理采用了IEE754标准的“0舍1入”法。
1. 浮点数的介绍在处理器中,数据不仅有符号,而且经常含有小数,即既有整数部分又有小数部分。
根据小数点位置是否固定,数的表示方法分为定点表示和浮点表示。
浮点数就是用浮点表示法表示的实数。
浮点数扩大了数的表示范围和精度。
浮点数由阶符、阶码E 、数符、尾数N 构成。
任意一个二进制数N 总可以表示成如下形式:N=。
通常规定:二进制浮点数,其尾数数字部分原码的最高位为1,叫作规格化表示法。
因此,扩大数的表示范围,就增加阶码的位数,要提高精度,就增加尾数的位数。
计算机设计与实践——32位先行进位加法器

assign c1=g[1]|p[1]&ciii; assign c2=g[2]|p[2]&g[1]|p[2]&p[1]&ciii; endmodule
module alu_16(gmm,pmm,f16,x16,y16,cii);//16位加法器先行进位加法器 input [16:1]x16; input [16:1]y16; input cii; output [16:1]f16; output gmm,pmm; wire [4:1]c; wire [4:1]p; wire [4:1]g; jiafaqi_4 alu_4_1(g[1],p[1],f16[4:1],x16[4:1],y16[4:1],cii); jiafaqi_4 alu_4_2(g[2],p[2],f16[8:5],x16[8:5],y16[8:5],c[1]); jiafaqi_4 alu_4_3(g[3],p[3],f16[12:9],x16[12:9],y16[12:9],c[2]); jiafaqi_4 alu_4_4(g[4],p[4],f16[16:13],x16[16:13],y16[16:13],c[3]); cla_4 cl_4_1(c,p,g,cii); assign pmm=p[4]&p[3]&p[2]&p[1]; assign gmm=g[4]|p[4]&g[3]|p[4]&p[3]&g[2]|p[4]&p[3]&p[2]&g[1]; endmodule
verilog实现加法器

verilog实现加法器半加器如果不考虑来⾃低位的进位将两个1⼆进制数相加,称为半加。
实现半加运算的逻辑电路称为半加器。
真值表>> 逻辑表达式和s=ab′+a′b>> 逻辑表达式进位输出co=abverilog codemodule halfadder(output s, //sumoutput co, //carryinput a,input b);assign s = a ^ b;assign co = a & b;//assign {co,s} = a + b;endmoduletestbenchmodule halfadder_tb;wire s;wire co;reg a;reg b;initialbegina = 0;b = 0;#10 a = 0 ;b = 0;#10 a = 0 ;b = 1;#10 a = 1 ;b = 0;#10 a = 1 ;b = 1;#10 $finish;endinitial begin$fsdbDumpfile("test.fsdb");$fsdbDumpvars();endhalfadder u_halfadder(.s(s),.co(co),.a(a),.b(b));endmodule全加器在将两位多位⼆进制数相加时,除了最低位以外,每位都应该考虑来⾃低位的进位,即将两个对应位的加数和来⾃低位的进位3个数相加。
这种运算称为全加,所⽤的电路称为全加器。
真值表逻辑表达式和s=(a′b′ci′+ab′ci+a′bci+abci′)′>> 逻辑表达式进位输出co=(a′b′+b′ci′+a′ci′)′verilog codemodule fulladder(output s, //sumoutput co, //carry to high bitinput a,input b,input ci //carry from low bit);//RTL levelassign s = ~((~a&~b&~ci)||(a&~b&ci)||(~a&b&ci)||(a&b&~ci));assign co = ~((~a&~b)||(~b&~ci)||(~a&~ci));//assign {co,s} = a + b + ci;endmoduletestbenchmodule fulladder_tb;wire s;wire co;reg a;reg b;reg ci;initialbeginci = 0; a = 0 ;b = 0;#10 ci = 0; a = 0 ;b = 1;#10 ci = 0; a = 1 ;b = 0;#10 ci = 0; a = 1 ;b = 1;#10 ci = 1; a = 0 ;b = 0;#10 ci = 1; a = 0 ;b = 1;#10 ci = 1; a = 1 ;b = 0;#10 ci = 1; a = 1 ;b = 1;#10 $finish;endinitial begin$fsdbDumpfile("test.fsdb");$fsdbDumpvars();endfulladder u_fulladder(.s(s),.co(co),.a(a),.b(b),.ci(ci));endmodule多位加法器串⾏进位加法器依次将低位全加器的进位输出co接到全加器的进位输⼊端ci,就可以构成多位加法器。
应用VHDL引用LPM库设计32位加法器

课程名称 EDA 学院电信专业电信班级三班学号姓名指导老师目录第一章、题目 (3)第二章、设计步骤 (4)第三章、设计心得 (40)第四章、参考文献 (41)第一章题目应用VHDL引用LPM库设计32位加法器。
要求在Quartus II软件,利用VHDL完成层次式电路设计,电路中的元件可以用VHDL设计也可以用库元件连线构成再封装。
借助EDA工具中的综合器,适配器,时序仿真器和编程器等工具进行相应处理。
输入方法不限制。
适配元件不限制。
要求综合出RTL电路,并进行仿真输入波形设计并分析电路输出波形。
第二章设计步骤新建工程输入设计项目并存盘:利用lpm_add_sub函数。
参数设定:引脚分配:程序清单:OPTIONS NAME_SUBSTITUTION = ON;INCLUDE "addcore";INCLUDE "look_add";INCLUDE "bypassff";INCLUDE "altshift";INCLUDE "alt_stratix_add_sub";INCLUDE "alt_mercury_add_sub";PARAMETERS(LPM_WIDTH,LPM_REPRESENTATION = "SIGNED",LPM_DIRECTION = "DEFAULT", -- controlled by add_sub portONE_INPUT_IS_CONSTANT = "NO",LPM_PIPELINE = 0,MAXIMIZE_SPEED = 5,REGISTERED_AT_END = 0,OPTIMIZE_FOR_SPEED = 5,USE_CS_BUFFERS = 1,CARRY_CHAIN = "IGNORE",CARRY_CHAIN_LENGTH = 32,DEVICE_FAMILY,USE_WYS = "OFF",STYLE = "NORMAL",CBXI_PARAMETER = "NOTHING");INCLUDE ""; % device family definitions %FUNCTION @CBXI_PARAMETER (aclr, add_sub, cin, clken, clock, dataa[LPM_WIDTH-1..0], datab[LPM_WIDTH-1.RETURNS (cout, overflow, result[LPM_WIDTH-1..0]);-- a useful macroDEFINE MIN(a, b) = a < b ? a : b;-- LPM_PIPELINE became the new name for LATENCY. Will keep LATENCY in the code.CONSTANT LATENCY = LPM_PIPELINE;-- Determine the effective speed (vs. size) optimization factor: If The local-- param is used, take it as the effective value, otherwise use the global value CONSTANT SPEED_MAX_FACTOR = USED(MAXIMIZE_SPEED) ?MAXIMIZE_SPEED : OPTIMIZE_FOR_SPEED;-- Internal and external latencyCONSTANT LAST_STAGE_INDEX = (REGISTERED_AT_END == 1) ? 1 : 0; CONSTANT INT_STAGES_NUM = LATENCY + 1 - LAST_STAGE_INDEX; CONSTANT INT_LATENCY = (LATENCY == 0) ? 1 : MIN(LPM_WIDTH, INT_STAGES_NUM);CONSTANT EXT_LATENCY = (LATENCY > LPM_WIDTH) ? (LATENCY - LPM_WIDTH) : 0;CONSTANT REG_LAST_ADDER = ((LATENCY >= LPM_WIDTH) # (REGISTERED_AT_END == 1)) ? 1 : 0;DEFINE OVFLOW_EXTRA_DEPTH() = (LPM_REPRESENTATION == "SIGNED" #LPM_REPRESENTATION == "UNSIGNED" & USED(add_sub)) ? REG_LAST_ADDER :-- Partial adders (for pipelined cases)CONSTANT RWIDTH = LPM_WIDTH MOD INT_LATENCY; -- # of adders on the right sideCONSTANT LWIDTH = INT_LATENCY - RWIDTH; -- # of adders on the left sideCONSTANT SUB_WIDTH1 = FLOOR(LPM_WIDTH DIV INT_LATENCY); -- Width of right-side addersCONSTANT SUB_WIDTH0 = SUB_WIDTH1 + 1; -- Width of left-side adders-- =====================================================-- Look-ahead adder section-- =====================================================-- Number of 8-bit adder blocks in carry-look-ahead casesCONSTANT LOOK_AHEAD_BLOCK_SIZE = 8;CONSTANT BLOCKS = CEIL(LPM_WIDTH DIV LOOK_AHEAD_BLOCK_SIZE);-- Will use the look-ahead adder?CONSTANT USE_LOOK_AHEAD = -(!((LPM_WIDTH < LOOK_AHEAD_BLOCK_SIZE) #((FAMILY_FLEX() == 1) &(USE_CARRY_CHAINS() # (!USE_CARRY_CHAINS() & SPEED_MAX_FACTOR <=(!(FAMILY_FLEX() == 1) &(STYLE == "NORMAL" & SPEED_MAX_FACTOR <= 5))));DEFINE CBX_FAMILY() = ((FAMILY_STRATIXII() == 1 #FAMILY_CYCLONEII() == 1) ? 1 : 0);SUBDESIGN lpm_add_sub(dataa[LPM_WIDTH-1..0] : INPUT = GND;datab[LPM_WIDTH-1..0] : INPUT = GND;cin : INPUT = GND;add_sub : INPUT = VCC;clock : INPUT = GND;aclr : INPUT = GND;clken : INPUT = VCC;result[LPM_WIDTH-1..0] : OUTPUT;cout : OUTPUT;overflow : OUTPUT;)V ARIABLEIF CBX_FAMILY() == 1 & CBXI_PARAMETER != "NOTHING" GENERATE auto_generated : @CBXI_PARAMETER WITH ( CBXI_PARAMETER = "NOTHING" );ELSE GENERATE-- Use wysiwyg implementation for mercury if USE_WYS option is turned on IF FAMILY_MERCURY() == 1 & USE_WYS == "ON" GENERATEmercury_adder : alt_mercury_add_sub WITH(LPM_WIDTH = LPM_WIDTH,LPM_REPRESENTATION = LPM_REPRESENTATION,LPM_DIRECTION = LPM_DIRECTION,ONE_INPUT_IS_CONSTANT = ONE_INPUT_IS_CONSTANT,LPM_PIPELINE = LPM_PIPELINE,MAXIMIZE_SPEED = MAXIMIZE_SPEED,REGISTERED_AT_END = REGISTERED_AT_END,OPTIMIZE_FOR_SPEED = OPTIMIZE_FOR_SPEED,USE_CS_BUFFERS = USE_CS_BUFFERS,CARRY_CHAIN_LENGTH = CARRY_CHAIN_LENGTH,STYLE = STYLE);ELSE GENERATE-- Use wysisyg implementation for stratix if USE_WYS is ON or add_sub signal is usedIF FAMILY_STRATIX() == 1 & (USE_WYS == "ON" # USED(add_sub)) & (USE_CARRY_CHAINS()) GENERATEstratix_adder : alt_stratix_add_sub WITH(LPM_WIDTH = LPM_WIDTH,LPM_REPRESENTATION = LPM_REPRESENTATION,LPM_DIRECTION = LPM_DIRECTION,ONE_INPUT_IS_CONSTANT = ONE_INPUT_IS_CONSTANT,LPM_PIPELINE = LPM_PIPELINE,MAXIMIZE_SPEED = MAXIMIZE_SPEED,REGISTERED_AT_END = REGISTERED_AT_END,OPTIMIZE_FOR_SPEED = OPTIMIZE_FOR_SPEED,USE_CS_BUFFERS = USE_CS_BUFFERS,CARRY_CHAIN_LENGTH = CARRY_CHAIN_LENGTH,STYLE = STYLE);ELSE GENERATEIF INT_LATENCY > 1 GENERATE-- carry-in nodecin_node : NODE;cout_node : NODE;unreg_cout_node : NODE;-- datab[] nodesIF (FAMILY_FLEX() == 1) GENERATEIF (USE_CARRY_CHAINS()) GENERATEIF USED(add_sub) & ONE_INPUT_IS_CONSTANT == "NO" GENERATEdatab_node[LPM_WIDTH-1..0] : LCELL;ELSE GENERATEdatab_node[LPM_WIDTH-1..0] : NODE;END GENERATE;ELSE GENERATEIF USED(add_sub) & ONE_INPUT_IS_CONSTANT == "NO" GENERATEdatab_node[LPM_WIDTH-1..0] : SOFT;ELSE GENERATEdatab_node[LPM_WIDTH-1..0] : NODE;END GENERATE;END GENERATE;ELSE GENERATEIF USED(add_sub) & ONE_INPUT_IS_CONSTANT == "NO" GENERATEdatab_node[LPM_WIDTH-1..0] : SOFT;ELSE GENERATEdatab_node[LPM_WIDTH-1..0] : SOFT;END GENERATE;END GENERATE;IF (LPM_REPRESENTATION == "UNSIGNED" & LPM_DIRECTION != "SUB") & USED(add_sub) GENERATEadd_sub_ff[INT_LATENCY-2..0] : bypassff WITH (WIDTH = 1);END GENERATE;------------------------------------------------ cases where pipeline structure is needed ------------------------------------------------IF !(FAMILY_FLEX() == 1) GENERATE------------------------------------ Non-FLEX cases------------------------------------ if a nonhomogenous adder, generate the longer (right side) addersIF RWIDTH > 0 GENERATEadder0[RWIDTH-1..0] : addcore WITH (WIDTH = SUB_WIDTH0,DIRECTION = "ADD",USE_CS_BUFFERS = USE_CS_BUFFERS);datab0_ff[INT_LATENCY-1..0][RWIDTH-1..0] : bypassffWITH (WIDTH = SUB_WIDTH0);END GENERATE;-- generate the shorter (left side) addersadder1[LWIDTH-1..0] : addcore WITH (WIDTH = SUB_WIDTH1,DIRECTION = "ADD",USE_CS_BUFFERS = USE_CS_BUFFERS);datab1_ff[INT_LATENCY-1..0][LWIDTH-1..0] : bypassff WITH (WIDTH = SUB_WIDTH1);-- dataa pipeline registersdataa_ff[INT_LATENCY-2..0] : bypassff WITH (WIDTH = LPM_WIDTH);ELSE GENERATE------------------------------------------------ FLEX cases -------------------------------------------------- if a nonhomogenous adder, generate the longer (right side) addersIF RWIDTH > 0 GENERATEadder0[RWIDTH-1..0] : addcore WITH (WIDTH = SUB_WIDTH0 + 1,DIRECTION = "ADD",USE_CS_BUFFERS = USE_CS_BUFFERS);IF RWIDTH > 1 GENERATEadder0_0[RWIDTH-1..1] : addcore WITH (WIDTH = SUB_WIDTH0 + 1,DIRECTION = "ADD",USE_CS_BUFFERS = USE_CS_BUFFERS);END GENERATE;adder1[LWIDTH-1..0] : addcore WITH (WIDTH = SUB_WIDTH1 + 1,DIRECTION = "ADD",USE_CS_BUFFERS = USE_CS_BUFFERS);adder1_0[LWIDTH-1..0] : addcore WITH (WIDTH = SUB_WIDTH1 + 1,DIRECTION = "ADD",USE_CS_BUFFERS = USE_CS_BUFFERS);datab0_ff[INT_LATENCY-1..0][RWIDTH-1..0] : bypassff WITH (WIDTH = SUB_WIDTH0+1);ELSE GENERATEadder1[LWIDTH-1..0] : addcore WITH (WIDTH = SUB_WIDTH1 + 1,DIRECTION = "ADD",USE_CS_BUFFERS = USE_CS_BUFFERS);IF LWIDTH > 1 GENERATEadder1_0[LWIDTH-1..1] : addcore WITH (WIDTH = SUB_WIDTH1 + 1,DIRECTION = "ADD",USE_CS_BUFFERS = USE_CS_BUFFERS);END GENERATE;END GENERATE;datab1_ff[INT_LATENCY-1..0][LWIDTH-1..0] : bypassff WITH (WIDTH = SUB_WIDTH1+1);IF LPM_REPRESENTATION == "SIGNED" GENERATEsign_ff[INT_LATENCY-2..0] : bypassff WITH (WIDTH = 2);END GENERATE;END GENERATE;ELSE GENERATE------------------------------------ non-pipelined adder cases -------------------------------------- Will use a look-ahead type adder for FLEX/NORMAL with SPEED_MAX_FACTOR > 5 or-- MAX/FAST cases. Will use a ripple type adder for all other cases.IF USED(clock) # (USE_LOOK_AHEAD == 0) GENERATEadder : addcore WITH (WIDTH = LPM_WIDTH, DIRECTION = LPM_DIRECTION,REPRESENTATION = LPM_REPRESENTATION,USE_CS_BUFFERS = USE_CS_BUFFERS);cout_node : NODE;oflow_node : NODE;ELSE GENERATEcin_node : NODE;cout_node : NODE;oflow_node : NODE;datab_node[LPM_WIDTH-1..0] : SOFT;adder[BLOCKS-1..0] : addcore WITH (WIDTH = 8,DIRECTION = "DEFAULT",USE_CS_BUFFERS = USE_CS_BUFFERS);look_ahead_unit : look_add WITH (WIDTH = BLOCKS);END GENERATE;END GENERATE;result_node [LPM_WIDTH-1..0] : NODE;result_ext_latency_ffs : altshift WITH (WIDTH = LPM_WIDTH,DEPTH = EXT_LATENCY);carry_ext_latency_ffs : altshift WITH (WIDTH = 1,DEPTH = EXT_LATENCY);oflow_ext_latency_ffs : altshift WITH (WIDTH = 1,DEPTH = EXT_LATENCY);END GENERATE; -- stratixEND GENERATE; --mercuryEND GENERATE; -- StratixIIBEGINASSERT REPORT "LPM_WIDTH = %" LPM_WIDTH SEVERITY DEBUG;ASSERT REPORT "LATENCY = %" LATENCY SEVERITY DEBUG;ASSERT REPORT "LWIDTH = %" LWIDTH SEVERITY DEBUG;ASSERT REPORT "RWIDTH = %" RWIDTH SEVERITY DEBUG;ASSERT REPORT "INT_LATENCY = %" INT_LATENCY SEVERITY DEBUG;ASSERT REPORT "EXT_LATENCY = %" EXT_LATENCY SEVERITY DEBUG;ASSERT REPORT "SUB_WIDTH1 = %" SUB_WIDTH1 SEVERITY DEBUG;ASSERT (LPM_REPRESENTATION == "SIGNED" # LPM_REPRESENTATION == "UNSIGNED")REPORT "Illegal value for LPM_REPRESENTATION parameter (""%"") -- value must be ""SIGNED"LPM_REPRESENTATIONSEVERITY ERRORHELP_ID LPM_ADD_SUB_REPRESENTATION;ASSERT (LPM_WIDTH > 0)REPORT "LPM_WIDTH parameter value must be greater than 0"SEVERITY ERRORHELP_ID LPM_ADD_SUB_WIDTH;ASSERT (USED(clock) ? LATENCY > 0 : LATENCY == 0)REPORT "Value of LPM_PIPELINE parameter must be greater than 0 if clock input is used andSEVERITY ERRORHELP_ID LPM_ADD_SUB_CLOCK_WITHOUT_LATENCY;ASSERT (LATENCY <= LPM_WIDTH)REPORT "Value of LPM_PIPELINE parameter (%) should be lower -- use % for best performanceSEVERITY INFOHELP_ID LPM_ADD_SUB_CLOCK_LATENCY_V ALUE;ASSERT (LPM_WIDTH > 0)REPORT "Value of LPM_WIDTH parameter must be greater than 0"SEVERITY ERRORHELP_ID LPM_ADD_SUB_WIDTH2;ASSERT (LPM_REPRESENTATION == "UNSIGNED" # LPM_REPRESENTATION == "SIGNED")REPORT "Illegal value for LPM_REPRESENTATION parameter (%) -- value must be UNSIGNED (theLPM_REPRESENTATIONSEVERITY ERRORHELP_ID LPM_ADD_SUB_REPRESENTATION2;ASSERT (ONE_INPUT_IS_CONSTANT == "YES" # ONE_INPUT_IS_CONSTANT == "NO")REPORT "Illegal value for ONE_INPUT_IS_CONSTANT parameter (%) -- value must be YES or NOONE_INPUT_IS_CONSTANTSEVERITY ERRORHELP_ID LPM_ADD_SUB_ICONSTANT;ASSERT (LPM_DIRECTION == "DEFAULT" # LPM_DIRECTION == "ADD" # LPM_DIRECTION == "SUB")REPORT "Illegal value for LPM_DIRECTION parameter (%) -- value must be ADD, SUB, or DEFAULPM_DIRECTIONSEVERITY ERRORHELP_ID LPM_ADD_SUB_DIRECTION;ASSERT (LPM_DIRECTION == "DEFAULT" # USED(add_sub) == 0)REPORT "Value of LPM_DIRECTION parameter (%) is not consistent with the use of the add_suLPM_DIRECTIONSEVERITY ERRORHELP_ID LPM_ADD_SUB_DIRECTION_ADD_SUB;-- The next assertion is not implemented because MAX+PLUS II implementation -- differs from the LPM standard. Both overflow and cout are allowed-- in MAX+PLUS II.-- ASSERT (USED(overflow) == 0 # USED(cout) == 0)-- REPORT "Can't use overflow port if cout port is used"-- SEVERITY ERROR-- HELP_ID LPM_ADD_SUB_OVERCOUT;ASSERT (FAMILY_IS_KNOWN() == 1)REPORT "Megafunction lpm_add_sub does not recognize the current device family (%) -- ensure tDEVICE_FAMILYSEVERITY WARNINGHELP_ID LPM_ADD_SUB_FAMILY_UNKNOWN;IF CBX_FAMILY() == 1 & CBXI_PARAMETER != "NOTHING" GENERATE IF USED(aclr) GENERATE= aclr;END GENERATE;IF USED(add_sub) GENERATE= add_sub;END GENERATE;IF USED(cin) GENERATE= cin;END GENERATE;IF USED(clken) GENERATE= clken;END GENERATE;IF USED(clock) GENERATE= clock;END GENERATE;IF USED(cout) GENERATEcout = ;END GENERATE;IF USED(dataa) GENERATE[] = dataa[];END GENERATE;IF USED(datab) GENERATE[] = datab[];END GENERATE;IF USED(overflow) GENERATEoverflow = ;END GENERATE;IF USED(result) GENERATEresult[] = [];END GENERATE;ELSE GENERATE------------------------------------------------------------------------ mercury wysiwyg adderIF FAMILY_MERCURY() == 1 & USE_WYS == "ON" GENERATE result[] = [];IF USED (cout) GENERATEcout = ;END GENERATE;IF USED(overflow) GENERATEoverflow = ;END GENERATE;[] = dataa[];[] = datab[];IF USED(cin) GENERATE= cin;END GENERATE;IF USED(clock) GENERATE= clock;END GENERATE;IF USED(aclr) GENERATE= aclr;END GENERATE;IF USED(clken) GENERATE= clken;END GENERATE;IF USED(add_sub) GENERATE= add_sub;END GENERATE;ELSE GENERATE-- stratix wysisyg adderIF FAMILY_STRATIX() == 1 & (USE_WYS == "ON" # USED(add_sub)) & (USE_CARRY_CHAINS()) GENERATEresult[] = [];IF USED(cout) GENERATEcout = ;END GENERATE;IF USED(overflow) GENERATEoverflow = ;END GENERATE;[] = dataa[];[] = datab[];IF USED(cin) GENERATE= cin;END GENERATE;IF USED(clock) GENERATE= clock;END GENERATE;IF USED(aclr) GENERATE= aclr;END GENERATE;IF USED(clken) GENERATE= clken;END GENERATE;IF USED(add_sub) GENERATE= add_sub;END GENERATE;ELSE GENERATE-- default addcore adderIF INT_LATENCY > 1 GENERATEIF USED(cin) GENERATEcin_node = cin;ELSE GENERATEIF LPM_DIRECTION == "SUB" GENERATEcin_node = VCC;ELSE GENERATEcin_node = !add_sub;END GENERATE;END GENERATE;IF (LPM_REPRESENTATION == "UNSIGNED" & LPM_DIRECTION != "SUB") & USED(add_sub) GENERATEadd_sub_ff[0].d[0] = add_sub;IF INT_LATENCY > 2 GENERATEadd_sub_ff[INT_LATENCY-2..1].d[0] = add_sub_ff[INT_LATENCY-3..0].q[0];END GENERATE;add_sub_ff[].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;IF LPM_DIRECTION == "SUB" GENERATEdatab_node[] = !datab[];ELSE GENERATEIF USED(add_sub) GENERATEdatab_node[] = datab[] $ !add_sub;ELSE GENERATEdatab_node[] = datab[];END GENERATE;END GENERATE;IF !(FAMILY_FLEX() == 1) GENERATE------------------------------------------------ non-FLEX cases------------------------------------------------ clock connections-- adders clock/aclr/clken/add_sub connectionsIF RWIDTH > 0 GENERATEadder0[RWIDTH-1..0].(clock, aclr, clken) = (clock, aclr, clken);IF (LWIDTH > 1) GENERATEadder1[LWIDTH-2..0].(clock, aclr, clken) = (clock, aclr, clken);END GENERATE;ELSE GENERATEIF LWIDTH > 1 GENERATEadder1[LWIDTH-2..0].(clock, aclr, clken) = (clock, aclr, clken);END GENERATE;END GENERATE;IF REG_LAST_ADDER == 1 GENERATEadder1[LWIDTH-1].(clock, aclr, clken) = (clock, aclr, clken);END GENERATE;dataa_ff[].(clk, clrn, ena) = (clock, !aclr, clken);IF RWIDTH > 0 GENERATEIF RWIDTH > 1 GENERATEdatab0_ff[0][RWIDTH-1..1].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;datab1_ff[0][LWIDTH-1..0].(clk, clrn, ena) = (clock, !aclr, clken);ELSE GENERATEdatab1_ff[0][LWIDTH-1..1].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;--carry_ff[INT_LATENCY-2..0].(clk, clrn, ena) = (clock, !aclr, clken);-- dataa connections as we have intermediate subaddersdataa_ff[0].d[] = dataa[];IF INT_LATENCY > 2 GENERATEdataa_ff[INT_LATENCY-2..1].d[] = dataa_ff[INT_LATENCY-3..0].q[];END GENERATE;-- datab input connectionsIF RWIDTH > 0 GENERATEIF RWIDTH > 1 GENERATEFOR I IN 1 TO RWIDTH-1 GENERATEdatab0_ff[0][I].d[] = datab_node[(I+1)*SUB_WIDTH0-1..I*SUB_WIDTH0];END GENERATE;END GENERATE;FOR I IN 0 TO LWIDTH-1 GENERATEdatab1_ff[0][I].d[] = datab_node[(I+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..I*SUB_WIDTH1+RWIDTH*SUB_WIDTH0];END GENERATE;ELSE GENERATEIF LWIDTH > 1 GENERATEFOR I IN 1 TO LWIDTH-1 GENERATEdatab1_ff[0][I].d[] = datab_node[(I+1)*SUB_WIDTH1-1..I*SUB_WIDTH1];END GENERATE;END GENERATE;END GENERATE;-- some adder connectionsIF RWIDTH > 0 GENERATE-- The nonhomogeneous adder case. Note that with RWIDTH > 0,-- INT_LATENCY must have been > 1.-- longer (right hand side) adder(s) connection(s)-- the upper right-most adder is connected to the input nodesadder0[0].dataa[] = dataa[SUB_WIDTH0-1..0];adder0[0].datab[] = datab_node[SUB_WIDTH0-1..0];adder0[0].cin = cin_node;-- if more than one right-side adder, make the input and carry connectionsIF RWIDTH > 1 GENERATEFOR I IN 1 TO RWIDTH-1 GENERATEadder0[I].dataa[] = dataa_ff[I-1].q[(I+1)*SUB_WIDTH0-1..I*SUB_WIDTH0];adder0[I].datab[] = datab0_ff[I-1][I].q[];adder0[I].cin = adder0[I-1].cout;END GENERATE;END GENERATE;-- first left-hand-side adder connectionsadder1[0].dataa[] = dataa_ff[RWIDTH-1].q[SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..RWIDTH*SU adder1[0].datab[] = datab1_ff[RWIDTH-1][0].q[];adder1[0].cin = adder0[RWIDTH-1].cout;ELSE GENERATE-- case with homogeneous addersadder1[0].dataa[] = dataa[SUB_WIDTH1-1..0];adder1[0].datab[] = datab_node[SUB_WIDTH1-1..0];adder1[0].cin = cin_node;END GENERATE;-- more connections if more than 1 left-hand-side adders existIF LWIDTH > 1 GENERATEFOR I IN 1 TO LWIDTH-1 GENERATEadder1[I].dataa[] = dataa_ff[I+RWIDTH-1].q[(I+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..I*SUB_WIDTH1+RWIDTH*SUB_WIDTH0];adder1[I].datab[] = datab1_ff[I+RWIDTH-1][I].q[];END GENERATE;adder1[LWIDTH-1..1].cin = adder1[LWIDTH-2..0].cout;END GENERATE;IF USED(cout) # USED(overflow) GENERATEcout_node = adder1[LWIDTH-1].cout;unreg_cout_node = adder1[LWIDTH-1].unreg_cout;ELSE GENERATEcout_node = GND;unreg_cout_node = GND;END GENERATE;ELSE GENERATE------------------------------------------------ FLEX cases -------------------------------------------------- adders clock/aclr/clken/add_sub connectionsIF RWIDTH > 0 GENERATEadder0[RWIDTH-1..0].(clock, aclr, clken) = (clock, aclr, clken);IF RWIDTH > 1 GENERATEadder0_0[RWIDTH-1..1].(clock, aclr, clken) = (clock, aclr, clken);END GENERATE;IF (LWIDTH > 1) GENERATEadder1[LWIDTH-2..0].(clock, aclr, clken) = (clock, aclr, clken);END GENERATE;adder1_0[LWIDTH-1..0].(clock, aclr, clken) = (clock, aclr, clken);ELSE GENERATEIF LWIDTH > 1 GENERATEadder1[LWIDTH-2..0].(clock, aclr, clken) = (clock, aclr, clken);adder1_0[LWIDTH-1..1].(clock, aclr, clken) = (clock, aclr, clken);END GENERATE;END GENERATE;IF REG_LAST_ADDER == 1 GENERATEadder1[LWIDTH-1].(clock, aclr, clken) = (clock, aclr, clken);END GENERATE;IF LPM_REPRESENTATION == "SIGNED" GENERATEsign_ff[INT_LATENCY-2..0].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;-- dataa & datab input connectionsIF RWIDTH > 0 GENERATEIF RWIDTH > 1 GENERATEFOR I IN 1 TO RWIDTH-1 GENERATEadder0_0[I].dataa[SUB_WIDTH0-1..0] = dataa[(I+1)*SUB_WIDTH0-1..I*SUB_WIDTH0];adder0_0[I].datab[SUB_WIDTH0-1..0] = datab_node[(I+1)*SUB_WIDTH0-1..I*SUB_WIDdatab0_ff[0][I].d[] = adder0_0[I].result[];END GENERATE;END GENERATE;FOR I IN 0 TO LWIDTH-1 GENERATEadder1_0[I].dataa[SUB_WIDTH1-1..0] = dataa[(I+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..I*SUB_WIDTH1+RWIDTH*SUB_WIDTH0];adder1_0[I].datab[SUB_WIDTH1-1..0] = datab_node[(I+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTHI*SUB_WIDTH1+RWIDTH*SUB_WIDTH0];datab1_ff[0][I].d[] = adder1_0[I].result[];END GENERATE;ELSE GENERATEIF LWIDTH > 1 GENERATEFOR I IN 1 TO LWIDTH-1 GENERATEadder1_0[I].dataa[SUB_WIDTH1-1..0] = dataa[(I+1)*SUB_WIDTH1-1..I*SUB_WIDTH1];adder1_0[I].datab[SUB_WIDTH1-1..0] = datab_node[(I+1)*SUB_WIDTH1-1..I*SUB_WIDdatab1_ff[0][I].d[] = adder1_0[I].result[];END GENERATE;END GENERATE;END GENERATE;-- adder and bypass nodes connectionsIF RWIDTH > 0 GENERATE-- The nonhomogeneous adder case. Note that with RWIDTH > 0,-- INT_LATENCY must have been > 1.-- longer (right hand side) adder(s) connection(s)-- the upper right-most adder is connected to the input nodesadder0[0].dataa[SUB_WIDTH0-1..0] = dataa[SUB_WIDTH0-1..0];adder0[0].datab[SUB_WIDTH0-1..0] = datab_node[SUB_WIDTH0-1..0];adder0[0].cin = cin_node;-- if more than one right-side adder, make the input and carry connectionsIF RWIDTH > 1 GENERATEFOR I IN 1 TO RWIDTH-1 GENERATEadder0[I].dataa[0] = adder0[I-1].result[SUB_WIDTH0];adder0[I].datab[] = datab0_ff[I-1][I].q[];END GENERATE;END GENERATE;-- first left-hand-side adder connectionsadder1[0].dataa[0] = adder0[RWIDTH-1].result[SUB_WIDTH0];adder1[0].datab[] = datab1_ff[RWIDTH-1][0].q[];ELSE GENERATE-- case with homogeneous addersadder1[0].dataa[SUB_WIDTH1-1..0] = dataa[SUB_WIDTH1-1..0];adder1[0].datab[SUB_WIDTH1-1..0] = datab_node[SUB_WIDTH1-1..0];adder1[0].cin = cin_node;END GENERATE;-- more connections if more than 1 left-hand-side adders existIF LWIDTH > 1 GENERATEFOR I IN 1 TO LWIDTH-1 GENERATEadder1[I].dataa[0] = adder1[I-1].result[SUB_WIDTH1];adder1[I].datab[] = datab1_ff[I+RWIDTH-1][I].q[];END GENERATE;END GENERATE;IF LPM_REPRESENTATION == "SIGNED" GENERATEsign_ff[0].d[] = (dataa[LPM_WIDTH-1], datab_node[LPM_WIDTH-1]);IF INT_LATENCY > 2 GENERATEFOR I IN 1 TO INT_LATENCY-2 GENERATEsign_ff[I].d[] = sign_ff[I-1].q[];END GENERATE;END GENERATE;END GENERATE;IF USED(cout) # USED(overflow) GENERATEcout_node = adder1[LWIDTH-1].result[SUB_WIDTH1];unreg_cout_node = adder1[LWIDTH-1].unreg_result[SUB_WIDTH1];ELSE GENERATEcout_node = GND;unreg_cout_node = GND;END GENERATE;END GENERATE;---------------------------- datab_ff connections ----------------------------IF RWIDTH > 0 GENERATE-- first quadrant connectionsFOR I IN 0 TO RWIDTH-1 GENERATEdatab0_ff[I][I].d[] = adder0[I].result[];END GENERATE;IF RWIDTH > 1 GENERATEIF RWIDTH > 2 GENERATEFOR I IN 1 TO RWIDTH-2 GENERATEdatab0_ff[I][RWIDTH-1..(I+1)].d[] = datab0_ff[I-1][RWIDTH-1..(I+1)].q[];datab0_ff[I][RWIDTH-1..(I+1)].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;END GENERATE;FOR I IN 1 TO RWIDTH-1 GENERATEdatab0_ff[I][I-1..0].d[] = datab0_ff[I-1][I-1..0].q[];datab0_ff[I][I-1..0].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;END GENERATE;-- fourth quadrant connectionsFOR I IN RWIDTH TO INT_LATENCY-1 GENERATEdatab0_ff[I][RWIDTH-1..0].d[] = datab0_ff[I-1][RWIDTH-1..0].q[];END GENERATE;IF (INT_LATENCY - RWIDTH) > 1 GENERATEFOR I IN RWIDTH TO INT_LATENCY-2 GENERATEdatab0_ff[I][RWIDTH-1..0].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;END GENERATE;IF REG_LAST_ADDER == 1 GENERATEdatab0_ff[INT_LATENCY-1][].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;-- second quadrant connectionsIF RWIDTH > 1 GENERATEFOR I IN 1 TO RWIDTH-1 GENERATEdatab1_ff[I][LWIDTH-1..0].d[] = datab1_ff[I-1][LWIDTH-1..0].q[];datab1_ff[I][LWIDTH-1..0].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;END GENERATE;-- datab1_ff interface between second and third quadrantsIF LWIDTH >1 GENERATEdatab1_ff[RWIDTH][LWIDTH-1..1].d[] = datab1_ff[RWIDTH-1][LWIDTH-1..1].q[];datab1_ff[RWIDTH][LWIDTH-1..1].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;END GENERATE;-- third quadrant connectionsFOR I IN 0 TO LWIDTH-1 GENERATEdatab1_ff[I+RWIDTH][I].d[] = adder1[I].result[];END GENERATE;IF LWIDTH > 1 GENERATEFOR I IN 1 TO LWIDTH-1 GENERATEdatab1_ff[I+RWIDTH][I-1..0].d[] = datab1_ff[I+RWIDTH-1][I-1..0].q[];END GENERATE;IF LWIDTH > 2 GENERATEFOR I IN 1 TO LWIDTH-2 GENERATEdatab1_ff[I+RWIDTH][I-1..0].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;FOR I IN 1 TO LWIDTH-2 GENERATEdatab1_ff[I+RWIDTH][LWIDTH-1..I+1].d[] =datab1_ff[I+RWIDTH-1][LWIDTH-1..I+1].q[]datab1_ff[I+RWIDTH][LWIDTH-1..I+1].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;END GENERATE;IF REG_LAST_ADDER == 1 GENERATEdatab1_ff[INT_LATENCY-1][LWIDTH-2..0].(clk, clrn, ena) = (clock, !aclr, clken);END GENERATE;END GENERATE;-- connections of last row to output nodes-- right sectionIF RWIDTH > 0 GENERATEFOR J IN 0 TO RWIDTH-1 GENERATEresult_node[(J+1)*SUB_WIDTH0-1..J*SUB_WIDTH0] = datab0_ff[INT_LATENCY-1][J].q[SUB_WIDTH0-1..0];END GENERATE;END GENERATE;-- left sectionFOR J IN 0 TO LWIDTH-1 GENERATEresult_node[(J+1)*SUB_WIDTH1+RWIDTH*SUB_WIDTH0-1..J*SUB_WIDT H1+RWIDTH*SUB_WIDTH0] =datab1_ff[INT_LATENCY-1][J].q[SUB_WIDTH1-1..0];END GENERATE;-- overflow detectionIF LPM_REPRESENTATION == "SIGNED" GENERATEIF !(FAMILY_FLEX() == 1) GENERATE[] = (datab1_ff[INT_LATENCY-2][LWIDTH-1].q[SUB_WIDTH1-1] !$dataa_ff[INT_LATENCY-2].q[LPM_WIDTH-1]) &(dataa_ff[INT_LATENCY-2].q[LPM_WIDTH-1] $adder1[LWIDTH-1].unreg_result[SUB_WIDTH1-1]);ELSE GENERATE[] = !(sign_ff[INT_LATENCY-2].q[0] $ sign_ff[INT_LATENCY-2]&(sign_ff[INT_LATENCY-2].q[0] $ adder1[LWIDTH-1].unrEND GENERATE;ELSE GENERATEIF LPM_DIRECTION == "SUB" GENERATE[] = !cout_node;ELSE GENERATEIF USED(add_sub) GENERATE[] = !add_sub_ff[INT_LATENCY-2].q[0] $ unreg_cout_node;ELSE GENERATE[] = cout_node;END GENERATE;END GENERATE;END GENERATE;ELSE GENERATE------------------------------------ non-pipelined adder cases ------------------------------------IF USED(clock) # (USE_LOOK_AHEAD == 0) GENERATE--------------------------------------------------- connections for a ripple carry adder-------------------------------------------------[] = dataa[];[] = datab[];result_node[] = [];IF USED(cin) GENERATE= cin;END GENERATE;IF USED(add_sub) GENERATE= add_sub;END GENERATE;IF USED(cout) GENERATEcout_node = ;ELSE GENERATEcout_node = GND;END GENERATE;IF USED(overflow) GENERATEoflow_node = ;ELSE GENERATEoflow_node = GND;。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//超前进位加法器
`define word_size 32
`define word [`word_size-1:0]
`define n 4
`define slice [`n-1:0]
`define s0 (1*`n)-1:0*`n
`define s1 (2*`n)-1:1*`n
`define s2 (3*`n)-1:2*`n
`define s3 (4*`n)-1:3*`n
`define s4 (5*`n)-1:4*`n
`define s5 (6*`n)-1:5*`n
`define s6 (7*`n)-1:6*`n
`define s7 (8*`n)-1:7*`n
module c_adder (a,b,cin,s,cout); //顶层模块
input`word a,b;
input cin;
output`word s;
output cout;
wire[7:0] gg,gp,gc; //
wire[3:0] ggg,ggp,ggc; //
wire gggg,gggp; //
//first level
bitslice i0(a[`s0],b[`s0],gc[0],s[`s0],gp[0],gg[0]); bitslice i1(a[`s1],b[`s1],gc[1],s[`s1],gp[1],gg[1]); bitslice i2(a[`s2],b[`s2],gc[2],s[`s2],gp[2],gg[2]); bitslice i3(a[`s3],b[`s3],gc[3],s[`s3],gp[3],gg[3]); bitslice i4(a[`s4],b[`s4],gc[4],s[`s4],gp[4],gg[4]); bitslice i5(a[`s5],b[`s5],gc[5],s[`s5],gp[5],gg[5]); bitslice i6(a[`s6],b[`s6],gc[6],s[`s6],gp[6],gg[6]); bitslice i7(a[`s7],b[`s7],gc[7],s[`s7],gp[7],gg[7]); //second level
cla c0(gp[3:0],gg[3:0],ggc[0],gc[3:0],ggp[0],ggg[0]); cla c1(gp[7:4],gg[7:4],ggc[1],gc[7:4],ggp[1],ggg[1]); assign ggp[3:2]=2'b11;
assign ggg[3:2]=2'b00;
//third level
cla c2(ggp,ggg,cin,ggc,gggp,gggg);
assign cout=gggg|(gggp&cin);
endmodule
//求和并按输出a,b,cin分组
module bitslice(a,b,cin,s,gp,gg);
input`slice a,b;
input cin;
output`slice s;
output gp,gg;
wire`slice p,g,c;
pg i1(a,b,p,g);
cla i2(p,g,cin,c,gp,gg);
sum i3(a,b,c,s);
endmodule
//计算传播值和产生值的PG模块
module pg(a,b,p,g);
input`slice a,b;
output `slice p,g;
assign p=a|b;
assign g=a&b;
endmodule
//计算sum值的sum模块
module sum(a,b,c,s);
input`slice a,b,c;
output`slice s;
wire`slice t=a^b;
assign s=t^c;
endmodule
//n-bit 超前进位模块
module cla (p,g,cin,c,gp,gg);
input`slice p,g; //输出的propagate bit (传送值)和generate bit(生成值)
input cin; //进位输入
output`slice c; //为每一位产生进位
output gp,gg; //传播值和进位制
function [99:0] do_cla; //该函数内将为每个位计算其进位值
input `slice p,g;
input cin;
begin: label
integer i;
reg gp,gg;
reg`slice c;
gp=p[0];
gg=g[0];
c[0]=cin;
for (i=1;i<`n;i=i+1)
begin
//C0=G0+P0C_1
//C1=G1+P1C0=(G1+P1G0)+P1P0C_1 gp=gp&p[i];
gg=(gg&p[i])|g[i];
c[i]=(c[i-1]&p[i-1])|g[i-1]; end
do_cla={c,gp,gg};
end
endfunction
assign {c,gp,gg}=do_cla(p,g,cin); endmodule。