Module 模塊例化的兩種方式:按埠位置例化、按埠名例化。 module top_module ( input a, input b, output out ); mod_a instance1 ( .in1(a), .in2(b), .out(out) ); endmodule Module ...
Module
模塊例化的兩種方式:按埠位置例化、按埠名例化。
module top_module ( input a, input b, output out ); mod_a instance1 ( .in1(a), .in2(b), .out(out) ); endmodule
Module pos
按埠順序例化。
module top_module ( input a, input b, input c, input d, output out1, output out2 ); mod_a inst(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 inst (.out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d)); endmodule
Module shift
例化三個寄存器實現一個移位寄存器。
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
Module shift8
八位的移位寄存器,使用了一個sel信號選通輸出,標準答案用的都是按埠順序例化,看起來會簡潔一些,但是不利於大型工程的維護和可閱讀性。
module top_module ( input clk, input [7:0] d, input [1:0] sel, output [7:0] q ); wire [7:0]q1; wire [7:0]q2; wire [7:0]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@(*) begin case(sel) 0:q=d; 1:q=q1; 2:q=q2; 3:q=q3; endcase end endmodule
Module add
題目要求使用兩個16位的加法器實現一個32位的加法器。
module top_module( input [31:0] a, input [31:0] b, output [31:0] sum ); wire cout; add16 adder1( a[15:0], b[15:0], 1'b0, sum[15:0], cout ); add16 adder2( a[31:16], b[31:16], cout, sum[31:16], ); endmodule
Module fadd
相比上一題多了一個一位的加法器模塊,16位加法器仍然提供。答案這裡使用了全加器的邏輯表達式:sum = a ^ b ^ cin
,cout = a&b | a&cin | b&cin,我這裡是取巧直接用了一個加法符號。
module top_module ( input [31:0] a, input [31:0] b, output [31:0] sum );// wire cout; add16 adder1( a[15:0], b[15:0], 1'b0, sum[15:0], cout ); add16 adder2( a[31:16], b[31:16], cout, sum[31:16], ); endmodule module add1 ( input a, input b, input cin, output sum, output cout ); // Full adder module here assign {cout,sum}=a+b+cin; endmodule
Module cseladd
前面用的行波進位(ripple carry)加法器有一個缺點:必須要等低位的計算結束後才能計算高位,這道題高位使用了兩個加法器,一個假設進位是0一個假設僅為是1,待低位完成計算後,只需要選通相應的數據通路即可。
module top_module( input [31:0] a, input [31:0] b, output [31:0] sum ); wire cout; wire [15:0] sum_temp1; wire [15:0] sum_temp2; add16 adder1( a[15:0], b[15:0], 1'b0, sum[15:0], cout ); add16 adder2( a[31:16], b[31:16], 0, sum_temp1, ); add16 adder3( a[31:16], b[31:16], 1, sum_temp2, ); assign sum[31:16] = cout?sum_temp2:sum_temp1; endmodule
Module addsub
加減器,減法通過將b取補碼實現,這裡直接將b與repeat之後的sub進行異或運算,實現了減法時將b取反。同時將低位的16位加法器的cin輸入sub,可以實現負數時的補碼運算,比較巧妙。
module top_module( input [31:0] a, input [31:0] b, input sub, output [31:0] sum ); wire cout; wire [31:0]b1; assign b1=b^{32{sub}}; add16 adder1( a[15:0], b1[15:0], sub, sum[15:0], cout ); add16 adder2( a[31:16], b1[31:16], cout, sum[31:16], ); endmodule
最後一道題還想了挺久,但是其實題目中和圖中已經告訴了sub連cin。