目录
定义连接线的时候,一定要注意位宽的问题,尤其是有矢量的情况下;在命名导线和模块实例时要小心:名称必须是唯一的;进行按位运算的时候,没有规定的情况两个操作数的位宽要相同
模块
模块的层次结构是通过实例化一个模块在另一个模块中创建的,只要使用的所有模块都属于同一个项目(因此编译器知道在哪里可以找到该模块)。
一个模块的代码不会写入另一个模块的主体中(不同模块的代码不嵌套)。
题目:实例化模块a,并将模块a和顶层模块进行连接,其中mod_a的定义如下
module mod_a ( input in1, input in2, output out );
// Module body
endmodule
按名称
module top_module ( input a, input b, output out );
mod_a mod_c
(
.in1 (a),
.in2 (b),
.out (out)
);
endmodule
通过名称将信号连接到模块的端口,即使端口列表发生变化,电线也能保持正确连接。
mod_a instance2 ( .out(wc), .in1(wa), .in2(wb) );
按位置
module top_module ( input a, input b, output out );
mod_a mod_a_inst(a,b,out);
endmodule//要注意顺序
实例化模块时,端口根据模块的声明从左到右连接。例如:
mod_a instance1 ( wa, wb, wc );
如果模块的端口列表发生更改,则还需要查找和更改模块的所有实例化以匹配新模块。
D触发器
一个具有两个输入和一个输出的模块(实现D触发器)。实例化其中三个,然后将它们连接在一起以形成长度为 3 的移位寄存器。端口需要连接到所有实例。
提供给您的模块是:module my_dff ( input clk, input d, output q );
请注意,要进行内部连接,需要声明一些电线。在命名电线和模块实例时要小心:名称必须是唯一的。
module top_module ( input clk, input d, output q );
wire dff12; //定义12之间的线
wire dff23; //定义23之间的线
my_dff a
(
.clk (clk) ,
.d (d) ,
.q (dff12)
);
my_dff b
(
.clk (clk) ,
.d (dff12) ,
.q (dff23)
);
my_dff c
(
.clk (clk) ,
.d (dff23) ,
.q (q)
);
endmodule
模块和矢量
模块端口不再是单个引脚,而是将矢量作为端口的模块,将向其附加线矢量而不是普通线路。
实例化三个模块并将它们连接起来,并写一个选择器,当sel为00时输出d,当sel为01时输出经过第一个触发器后的q值,以此类推。这里选择用case语句来实现。需要注意的是定义新的连接线时,要注意线位宽问题,如果没有定义则会给出警告
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0] dff12; //定义12之间的连接线
wire [7:0] dff23; //定义23之间的连接线
wire [7:0] dff3m; //定义3和选择器的连接线
my_dff8 a(.clk(clk), .d(d), .q(dff12));
my_dff8 b(.clk(clk), .d(dff12),.q(dff23));
my_dff8 c(.clk(clk), .d(dff23),.q(dff3m));
always@(*)
case(sel)
2'b00 : q = d;
2'b01 : q = dff12;
2'b10 : q = dff23;
2'b11 : q = dff3m;
endcase
endmodule
官网提供的参考答案
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output reg [7:0] q
);
wire [7:0] o1, o2, o3; // output of each my_dff8
// Instantiate three my_dff8s
my_dff8 d1 ( clk, d, o1 );
my_dff8 d2 ( clk, o1, o2 );
my_dff8 d3 ( clk, o2, o3 );
// This is one way to make a 4-to-1 multiplexer
always @(*) // Combinational always block
case(sel)
2'h0: q = d;
2'h1: q = o1;
2'h2: q = o2;
2'h3: q = o3;
endcase
endmodule
加法器
提供的模块具有以下声明:add16
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
实例化两个加法器,加法器1对输入的低位进行运算,加法器2对输入的高位进行运算,将它们在内部进行连接,并将最后的结果赋值给顶层模块的sum
全加器
此设计中有三个模块:
top_module
— 您的顶级模块包含两个...add16
,提供 — 一个 16 位加法器模块,由 16 个...add1
— 一个 1 位全加法器模块。
/*我的解答*/
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [0:0] add12; //定义第一个加法器与第二个加法器的连接线
wire [15:0] sum1; //定义第一个加法器的输出线
wire [31:16] sum2; //定义第二个加法器的输出线
add16 add16_inst1(
.a(a[15:0]) ,
.b(b[15:0]) ,
.cout(add12) ,
.sum(sum1)
);
add16 add16_inst2(
.a(a[31:16]) ,
.b(b[31:16]) ,
.cin(add12) ,
.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
同步加法器
提供的模块具有以下声明:add16
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
实例化三个加法器,然后根据图示进行连接,选择器用case语句完成
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [0:0] sel ; //定义一位的选择信号
wire [15:0] sum1; //定义第一个加法器的输出线
wire [31:16] sum2; //定义第二个加法器的输出线
wire [31:16] sum3; //定义第三个加法器的输出线
add16 add16_inst1(
.a(a[15:0]) ,
.b(b[15:0]) ,
.cout(sel) ,
.cin(1'b0) ,
.sum(sum1)
);
add16 add16_inst2(
.a(a[31:16]) ,
.b(b[31:16]) ,
.cin(1'b0) ,
.cout( ) ,
.sum(sum2)
);
add16 add16_inst3(
.a(a[31:16]) ,
.b(b[31:16]) ,
.cout( ) ,
.cin(1'b1) ,
.sum(sum3) ,
);
always@(*)
case(sel)
1'b0 : sum = {sum2,sum1};
1'b1 : sum = {sum3,sum1};
endcase
endmodule
减法器
提供了一个 16 位加法器模块
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
需要注意的是异或时位宽需要一样,也就是sub也需要是32位的,否则最后的结果是错误的,可以利用{}进行复制的操作
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire [31:0] xor_wire; //定义经过xor门后的输出线
wire [0:0] add12; //定义第一个加法器与第二个加法器的连接线
wire [15:0] sum1; //定义第一个加法器的输出线
wire [31:16] sum2; //定义第二个加法器的输出线
assign xor_wire = {32{sub}} ^ b;
add16 add16_inst1(
.a(a[15:0]) ,
.b(xor_wire[15:0]) ,
.cin(sub) ,
.cout(add12) ,
.sum(sum1)
);
add16 add16_inst2(
.a(a[31:16]) ,
.b(xor_wire[31:16]) ,
.cin(add12) ,
.cout( ) ,
.sum(sum2)
);
assign sum = {sum2,sum1};
endmodule