目录
一、 Module cseladd
https://hdlbits.01xz.net/wiki/Module_cseladd
(1)题目
One drawback of the ripple carry adder (See previous exercise) is that the delay for an adder to compute the carry out (from the carry-in, in the worst case) is fairly slow, and the second-stage adder cannot begin computing its carry-out until the first-stage adder has finished. This makes the adder slow. One improvement is a carry-select adder, shown below. The first-stage adder is the same as before, but we duplicate the second-stage adder, one assuming carry-in=0 and one assuming carry-in=1, then using a fast 2-to-1 multiplexer to select which result happened to be correct.
In this exercise, you are provided with the same module
add16
as the previous exercise, which adds two 16-bit numbers with carry-in and produces a carry-out and 16-bit sum. You must instantiate three of these to build the carry-select adder, using your own 16-bit 2-to-1 multiplexer.Connect the modules together as shown in the diagram below. The provided module
add16
has the following declaration:
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
翻译:
纹波进位加法器的一个缺点(见前面的练习)是加法器计算进位的延迟(在最坏的情况下是从进位开始)相当慢,并且第二阶段加法器直到第一阶段加法器完成后才能开始计算其进位。这使得加法器变慢。一个改进是进位选择加法器,如下所示。第一阶段加法器与之前相同,但我们复制了第二阶段加法器,一个假设携带=0,另一个假设携带=1,然后使用快速2对1多路复用器选择碰巧正确的结果。
在本练习中,为您提供了与前一个练习相同的模块add16,该模块将两个16位数字加在一起,并生成一个携带和16位和。您必须实例化其中的三个以使用您自己的16位2对1多路复用器构建进位选择加法器。
模块连接到一起,如下图所示。所提供的模块add16有以下声明:
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
(2) 分析+代码
本题考察例化语法,需要例化三个add16来计算图中的三个sum。其中标号为1的add16的cout输出决定二选一选择器的输出。若为cout=1,则sum[15:0]为标号3的sum;若cout=0,则sum[15:0]为标号2的sum。
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0]sum1,sum2,sum3,sum4;
wire cout;
add16 add16_1(.a(a[15:0]),.b(b[15:0]),.cin(0),.sum(sum1),.cout(cout));
add16 add16_2(.a(a[31:16]),.b(b[31:16]),.cin(0),.sum(sum2),.cout());
add16 add16_3(.a(a[31:16]),.b(b[31:16]),.cin(1),.sum(sum3),.cout());
always@(*)begin
if (cout==1)
sum4=sum3;
else
sum4=sum2;
end
assign sum={sum4,sum1};
endmodule
(3)结果
(4)零零碎碎
1. always语句中不能有assign赋值语句
在 Verilog 中,
always
块用于描述时序逻辑,而assign
语句用于描述组合逻辑。因此,在always
块中不能使用assign
语句。assign
主要用于为组合逻辑信号分配值,而always
块用于描述时钟边沿敏感的逻辑。2. 例化语句
模块:module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
(1)位置关联法 (一一对应)
add16 add16_1(a[15:0],b[15:0],0,sum1,cout);
(2)端口名关联法
add16 add16_1(.a(a[15:0]),.b(b[15:0]),.cin(0),.sum(sum1),.cout(cout));
括号外面的为模块元件端口名,括号里面的为例化元件的外接端口名。
二、 Module addsub
https://hdlbits.01xz.net/wiki/Module_addsub
(1)题目
An adder-subtractor can be built from an adder by optionally negating one of the inputs, which is equivalent to inverting the input then adding 1. The net result is a circuit that can do two operations: (a + b + 0) and (a + ~b + 1). See Wikipedia if you want a more detailed explanation of how this circuit works.
Build the adder-subtractor below.
You are provided with a 16-bit adder module, which you need to instantiate twice:
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
翻译:
加减法器可以由加法器构建,可选地减去其中一个输入,这相当于将输入反转然后加1。最终的结果是一个电路可以做两种操作:(a + b + 0)和(a + ~b + 1)。如果你想要更详细的解释这个电路是如何工作的,请参阅维基百科。
构建下面的加减法器。
您将获得一个16位加法器模块,您需要实例化两次:
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
(2)分析+代码
本题的考点同样是例化语句。其次,另一个考点是异或门的写法。或非门的写法有很多,我是用for循环让b的每一位与sub进行比较,相同为0,相异为1。
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire [15:0] sum1,sum2;
reg [31:0] b1;
wire cout1;
integer i;
always @(*)begin
for (i=0;i<32;i++)begin
if (sub==b[i])
b1[i]=0;
else
b1[i]=1;
end
end
add16 sum_1(.a(a[15:0]),.b(b1[15:0]),.cin(sub),.sum(sum1),.cout(cout1));
add16 sum_2(.a(a[31:16]),.b(b1[31:16]),.cin(cout1),.sum(sum2),.cout());
assign sum={sum2,sum1};
endmodule