Modules: Hierarchy
Modules
原題:Modules
說明如何引用module。
Verilog
module top_module ( input a, input b, output out );
mod_a moda(.out(out),.in1(a),.in2(b));
endmodule
Connecting ports by position
和前一題類似,題目要求我們依照argument的位置接線。
Verilog
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
module mod_a ( out1, out2, a, b, c, d );
endmodule
Connecting ports by name
和前一題不同,這裡改用 argument name 做 port mapping。
Verilog
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a moda(.out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d));
endmodule
Three modules
練習用接線的方式,將3個dff串接在一起。
Verilog
module top_module ( input clk, input d, output q );
wire q1,q2;
my_dff dff1( .clk(clk), .d(d), .q(q1));
my_dff dff2( .clk(clk), .d(q1), .q(q2));
my_dff dff3( .clk(clk), .d(q2), .q(q));
endmodule
Modules and vectors
和前一題類似,只是後面多接了一個multiplexer。而multiplexer可以用always block實現,速度會比用if/else還快,而因為multiplexer是combinational logic,所以要用blocking assignments。
Verilog
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 dff1( .clk(clk), .d(d), .q(q1));
my_dff8 dff2( .clk(clk), .d(q1), .q(q2));
my_dff8 dff3( .clk(clk), .d(q2), .q(q3));
always @(*)
case(sel)
2'b00: q = d;
2'b01: q = q1;
2'b10: q = q2;
2'b11: q = q3;
endcase
endmodule
Adder 1
原題:Adder 1
把兩個16 bit adder接在一起,值得注意的是,如果argument不想接線,直接留空就行了。
Verilog
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire c1;
add16 add_1( .a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum[15:0]), .cout(c1));
add16 add_2( .a(a[31:16]), .b(b[31:16]), .cin(c1), .sum(sum[31:16]), .cout());
endmodule
Adder 2
原題:Adder 2
和前一題類似,只是要多寫一個1 bit full adder,可以用concatenation來實現。
Verilog
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire c1;
add16 add_1( .a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum[15:0]), .cout(c1));
add16 add_2( .a(a[31:16]), .b(b[31:16]), .cin(c1), .sum(sum[31:16]), .cout());
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
assign {cout, sum} = a + b + cin;
endmodule
Carry-select adder
需要我們接線CSA(carry-select adder),CSA的好處在於已經偷算完cin是0和1的case,等到低位元進位後,就能馬上用multiplexer輸出算好的結果,缺點就是因為同時要算cin是0和1的結果,面積會變兩倍。
Verilog
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire sel;
wire [15:0] s1,s2;
add16 add1( .a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum[15:0]), .cout(sel));
add16 add2( .a(a[31:16]), .b(b[31:16]), .cin(1'b0), .sum(s1), .cout());
add16 add3( .a(a[31:16]), .b(b[31:16]), .cin(1'b1), .sum(s2), .cout());
always @(*)
case(sel)
1'b0: sum[31:16] = s1;
1'b1: sum[31:16] = s2;
endcase
endmodule
Adder-subtractor
說明如何快速實現減法,也就是a - b = a + ~(b) + 1這件事。
Verilog
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire c1;
wire [31:0] b_xor;
assign b_xor = b ^ {32{sub}};
add16 add_1( .a(a[15:0]), .b(b_xor[15:0]), .cin(sub), .sum(sum[15:0]), .cout(c1));
add16 add_2( .a(a[31:16]), .b(b_xor[31:16]), .cin(c1), .sum(sum[31:16]), .cout());
endmodule