module
1,分别用模块端口名字(name),模块端口参数位置(position)实现调用子模块。
by position:One drawback of this syntax is that if the module's port list changes, all instantiations of the module will also need to be found and changed to match the new module.
by name:Notice how the ordering of ports is irrelevant here because the connection will be made to the correct name, regardless of its position in the sub-module's port list
总的说,position 比较符合C语言习惯易懂,但是参数位置不能随便改。name法则对参数位置随便
module top_module ( input a, input b, output out );
mod_a mod1(.in1(a),.in2(b),.out(out));//模块名字 参数位置不受限制
//mod_a mod1(.out(out),.in1(a),.in2(b));
//mod_a mod1(a,b,out);//模块位置,随参数位置变化变化
endmodule
2 module by position
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a (out1,out2,a,b,c,d);
endmodule
3 module by name:
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a(.in1(a),.in2(b),.in3(c),.in4(d),.out1(out1),.out2(out2));
endmodule
//可见参数一一对应,位置不需考虑。
4 module shift
由图片可知需要初始化三个D触发器,模块内部有5个信号线,外部输入的CLK,D 信号,还有输出信号q,还有内部三个触发器之间通信的2个信号线。命名为wire Q1,Q2。
module top_module ( input clk, input d, output q );
wire Q1,Q2;
my_dff(.clk(clk),.d(d),.q(Q1));
my_dff(.clk(clk),.d(Q1),.q(Q2));
my_dff(.clk(clk),.d(Q2),.q(q));
endmodule
5 module shift8
3个8位D触发器,之后有一个4选一(用always@(*))
类似上个实验,只是输入信号变成8位vector ,输出多了个4选一
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire[7:0]q1,q2,q3;
my_dff8 mod1(.clk(clk),.d(d),.q(q1));
my_dff8 mod2(.clk(clk),.d(q1),.q(q2));
my_dff8 mod3(.clk(clk),.d(q2),.q(q3));
always@(*)begin
case(sel)
0:q=d;
1:q=q1;
2:q=q2;
3:q=q3;
endcase
end
endmodule
6 module adder1
加法器程序 adder1
引用的模块add16在网站上有,但是无需编写提交,主模块直接引用add16即可。
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cin1,cin2,cout1,cout2;
wire [15:0] sum1,sum2;
assign cin1=0;
assign cin2=cout1;
add16 instance1(.a(a[15:0]), .b(b[15:0]), .cin(cin1), .cout(cout1), .sum(sum1));
add16 instance2(.a(a[31:16]), .b(b[31:16]), .cin(cin2), .cout(cout2), .sum(sum2));
assign sum = {sum2, sum1}; //[31:0] sum={sum2,sum1};
endmodule
7 加法器程序fadd:
32位加法器,由两个add16 modules 组成,而每个module add16则是由1位全加器级联而成。
需要初始化1位全加器程序。
全加器提示:
Full adder equations:
sum = a ^ b ^ cin
cout = a&b | a&cin | b&cin
所以综合上次加法器的练习,添加add1 module
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire cin1,cin2,cout1,cout2;
wire [15:0] sum1,sum2;
assign cin1=0;
assign cin2=cout1;
add16 instance1(.a(a[15:0]), .b(b[15:0]), .cin(cin1), .cout(cout1), .sum(sum1));
add16 instance2(.a(a[31:16]), .b(b[31:16]), .cin(cin2), .cout(cout2), .sum(sum2));
assign sum = {sum2, sum1}; //[31:0] sum={sum2,sum1};
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
// Full adder module here
assign sum = a ^ b ^ cin;
assign cout = a&b | a&cin | b&cin;
endmodule
8 加法器的改进
之前练习的加法器有着较长的延时,所以针对对这情况进行了改进。三个16 adder加法器并行处理
一个处理a,b的【15:0】位相加看有无进位,
assign cout = a&b | a&cin | b&cin;
另外两个处理cin=1,0时候结果。
最后用2选一来输出结果。
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire cin1, cout1, cin2, cout2, cin3, cout3;
wire [15:0] sum1, sum2, sum3, sum4;
assign cin1 = 0;//检查是否需要进位
assign cin2 = 0;//cin=0
assign cin3 = 1;//cin=1
add16 instance1(.a(a[15:0]), .b(b[15:0]), .cin(cin1), .cout(cout1), .sum(sum1));
add16 instance2(.a(a[31:16]), .b(b[31:16]), .cin(cin2), .cout(cout2), .sum(sum2));
add16 instance3(.a(a[31:16]), .b(b[31:16]), .cin(cin3), .cout(cout3), .sum(sum3));
always @(*) begin
case(cout1)
0 : sum4= sum2;//无需进位,选sum2
1 : sum4 = sum3;//需要进位,选择sum3
endcase
end
assign sum = {sum4, sum1};//组合逻辑得出结果
endmodule
9 加减器
略