目录
写在前面
这部分主要就直接给答案及波形仿真图像,对一些题目的细节可能会说明一下。
Modules: Hierarchy
Module
例化模块
按名称将信号连接到模块的端口允许电线保持正确连接,即使端口列表发生变化。
mod_a instance2 (
.out(wc),
.in1(wa),
.in2(wb)
);
上面的行实例化一个名为“instance2”类型的模块,然后将信号(模块外部)连接到名为 的端口、名为 的端口和名为 的端口。请注意,端口的顺序在这里是无关紧要的,因为无论它在子模块的端口列表中的位置如何,都将建立正确的名称。
module top_module (
input a,
input b,
output out
);
mod_a mod_a_inst (
.out(out),
.in1(a),
.in2(b)
);
endmodule
仿真波形
Module pos
将获得一个名为 mod_a 的模块,该模块具有 2 个输出和 4 个输入(按该顺序排列)。
必须按位置将 6 个端口按该顺序连接到顶级模块的端口。
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a u_mod_a(out1,out2,a,b,c,d);
endmodule
仿真波形
Module name
例化模块,端口对应的连接。
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a mod_a_inst (
.in1(a),
.in2(b),
.in3(c),
.in4(d),
.out1(out1),
.out2(out2)
);
endmodule
仿真波形
Module shift
将获得一个具有两个输入和一个输出的模块(实现D触发器)。实例化其中的三个,然后将它们链接在一起以形成长度为3的移位寄存器。该端口需要连接到所有实例。
提供给您的模块是:
module my_dff (
input clk,
input d,
output q
);
请注意,要进行内部连接,您需要声明一些电线。在命名线路和模块实例时要小心:名称必须是唯一的。
module top_module (
input clk,
input d,
output q
);
wire shift1;
wire shift2;
my_dff my_dff_inst(
.clk(clk),
.d(d),
.q(shift1)
);
my_dff my_dff_u(
.clk(clk),
.d(shift1),
.q(shift2)
);
my_dff inst_my_dff(
.clk(clk),
.d(shift2),
.q(q)
);
endmodule
仿真波形
Module shift8
一个具有两个输入和一个输出的模块(实现一组8 D触发器)。实例化其中的三个,然后将它们链接在一起,形成长度为 3 的 8 位宽移位寄存器。此外,创建一个4对1多路复用器(未提供),该多路复用器选择输出内容取决于:输入d处的值,第一个D之后,第二个多路复用器之后,或第三个D触发器之后的值。实质上,选择延迟输入的周期数,从零到三个时钟周期。
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0] shift1;
wire [7:0] shift2;
wire [7:0] shift3;
my_dff8 my_dff8_inst(
.clk(clk),
.d(d),
.q(shift1)
);
my_dff8 my_dff8_u(
.clk(clk),
.d(shift1),
.q(shift2)
);
my_dff8 inst_my_dff8(
.clk(clk),
.d(shift2),
.q(shift3)
);
always @(*) begin
case(sel)
0:begin
q = d;
end
1:begin
q = shift1;
end
2:begin
q = shift2;
end
3:begin
q = shift3;
end
endcase
end
endmodule
仿真波形
Module add
一个执行 16 位加法的模块。实例化其中两个以创建 32 位加法器。一个 add16 模块计算加法结果的下 16 位,而第二个 add16 模块在收到来自第一个加法器的执行后,计算结果的上限 16 位。32 位加法器不需要处理携带(假设 0)或执行(忽略),但内部模块需要处理才能正常工作。(换句话说,模块执行 16 位 a + b + cin,而模块执行 32 位 a + b)。
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum1;
wire [15:0] sum2;
wire cout;
add16 add16_inst_l(
.a(a[15:0]),
.b(b[15:0]),
.cin('d0),
.cout(cout),
.sum(sum1)
);
add16 add16_inst_h(
.a(a[31:16]),
.b(b[31:16]),
.cin(cout),
.sum(sum2)
);
assign sum = {sum2,sum1};
endmodule
仿真波形
Module fadd
一个执行 16 位加法的模块。必须实例化其中两个才能创建 32 位加法器。一个模块计算加法结果的下16位,而第二个模块计算结果的上限16位。32 位加法器不需要处理携带(假设 0)或执行(忽略)。
module add16 (
input[15:0] a,
input[15:0] b,
input cin,
output[15:0] sum,
output cout
);
在每个中,16个完整的加法器(模块,未提供)被实例化以实际执行加法。
必须编写具有以下声明的完整 adder 模块
module add1 (
input a,
input b,
input cin,
output sum,
output cout
);
此设计中有三个模块:
top_module 顶层模块,其中包含两个add16,提供一个 16 位加法器模块,由 16 个add1一个 1 位完整加法器模块。
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum1;
wire [15:0] sum2;
wire cout;
add16 add16_inst_l(
.a(a[15:0]),
.b(b[15:0]),
.cin('d0),
.cout(cout),
.sum(sum1)
);
add16 add16_inst_h(
.a(a[31:16]),
.b(b[31:16]),
.cin(cout),
.sum(sum2)
);
assign sum = {sum2,sum1};
endmodule
module add1 (
input a,
input b,
input cin,
output sum,
output cout
);
assign {cout,sum} = a+b+cin;
endmodule
仿真波形
Module cseladd
选择加法器的缺点是加法器计算的延迟,要得到上一级的进位值才能进行下一级的计算。改进的方法是使用选择加法器。第一阶段加法器与以前相同,但我们复制第二级加法器,假设一个进位为0,另一个进位为1,使用2对1多路复用器来选择哪个结果恰好是正确的。提供与上一个练习相同的模块,该模块将两个16位数字相加,并生成一个进位和16位总和必须实例化其中的三个,才能使用自己的16位2对1多路复用器构建携带选择加法器。
module add16 (
input[15:0] a,
input[15:0] b,
input cin,
output[15:0] sum,
output cout
);
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] sum1;
wire [15:0] sum2;
wire [15:0] sum3;
wire cout;
add16 add16_inst_l(
.a(a[15:0]),
.b(b[15:0]),
.cin('d0),
.cout(cout),
.sum(sum1)
);
add16 add16_inst_h_0(
.a(a[31:16]),
.b(b[31:16]),
.cin('d0),
.sum(sum2)
);
add16 add16_inst_h_1(
.a(a[31:16]),
.b(b[31:16]),
.cin('d1),
.sum(sum3)
);
always @(*) begin
case(cout)
0:begin
sum = {sum2,sum1};
end
1:begin
sum = {sum3,sum1};
end
endcase
end
endmodule
仿真波形
Module addsub
加法器-减法器可以通过选择性地否定其中一个输入从加法器构建,这相当于反转输入然后添加1。
最终结果是一个可以执行两个操作的电路:(a + b + 0)和(a + ~b + 1)。
与 0 异或保持不变,与 1 异或相当于取反。
提供了一个 16 位加法器模块,您需要对其进行实例化两次:
module add16 (
input[15:0] a,
input[15:0] b,
input cin,
output[15:0] sum,
output cout
);
使用 32 位宽 XOR 栅极,在 sub 为 1 时反转 b 输入。(这也可以看作是b[31:0]XORed,
子复制了32次。看复制运算符)还要将子输入连接到加法器的随身。
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
reg [31:0] c;
wire [15:0] sum1;
wire [15:0] sum2;
wire cout;
always @(*) begin
if (~sub) begin
c = b;
end
else begin
c = ~b;
end
end
add16 add16_inst_l(
.a(a[15:0]),
.b(c[15:0]),
.cin(sub),
.cout(cout),
.sum(sum1)
);
add16 add16_inst_h(
.a(a[31:16]),
.b(c[31:16]),
.cin(cout),
.sum(sum2)
);
assign sum = {sum2,sum1};
endmodule
仿真波形