初識FPGA:各種RTL小型電路模組的設計
一、4選1多路選擇器
1、實現程式碼舉例
module top(out,in0,in1,in2,in3,sel);
parameter wl=2;
Output out;
input in0,in1,in2,in3;
input [wl-1:0] sel;
reg out;
always @(in0 or in1 or in2 or in3 or sel) //敏感訊號列表
begin
case(sel)
2'b00: out=in0;
2'b01: out=in1;
2'b10: out=in2;
2'b11: out=in3;
default: out=0;
endcase
end
endmodule
2、模擬RTL圖
3、模擬波形圖
二、4X4路交叉開關
實際上是選擇器的組合體,通常用在複雜一些的訊號選通的場合。每一個輸出端都有對應的選通訊號,用選通訊號控制輸出端選通到哪個輸入端。當輸入和輸出的埠增加時,該電路會消耗非常多的電路資源。
1、實現程式碼舉例
module top( IN0, IN1 ,IN2 , IN3 , SEL0,SEL1,SEL2,SEL3,OUT0,OUT1,OUT2, OUT3);
parameter wl=2;
input IN0,IN1,IN2,IN3;
input [wl-1:0]SEL0, SEL1, SEL2, SEL3;
output OUT0, OUT1,OUT2,OUT3;
reg OUT0, OUT1,OUT2,OUT3;
always @ (IN0 or IN1 or IN2 or IN3 or SEL0 ) begin
case(SEL0)
2'b00: OUT0 = IN0;
2'b01: OUT0 = IN1;
2'b10: OUT0 = IN2;
2'b11: OUT0 = IN3;
endcase
end
always @ (IN0 or IN1 or IN2 or IN3 or SEL1 ) begin
case(SEL1)
2'b00: OUT1 = IN0;
2'b01: OUT1 = IN1;
2'b10: OUT1 = IN2;
2'b11: OUT1 = IN3;
endcase
end
always @ (IN0 or IN1 or IN2 or IN3 or SEL2 ) begin
case(SEL2)
2'b00: OUT2 = IN0;
2'b01: OUT2 = IN1;
2'b10: OUT2 = IN2;
2'b11: OUT2 = IN3;
endcase
end
always @ (IN0 or IN1 or IN2 or IN3 or SEL3 ) begin
case(SEL3)
2'b00: OUT3 = IN0;
2'b01: OUT3 = IN1;
2'b10: OUT3 = IN2;
2'b11: OUT3 = IN3;
endcase
end
endmodule
2、模擬RTL圖
三、8輸入的優先編碼器
1、實現程式碼舉例
module top( IN , OUT );
input [7:0] IN;
output[3:0] OUT;
reg [3:0] OUT;
always @ (IN) begin
if(IN[7])
OUT = 4'b0111;
else if(IN[6])
OUT = 4'b0110;
else if(IN[5])
OUT = 4'b0101;
else if(IN[4])
OUT = 4'b0100;
else if(IN[3])
OUT = 4'b0011;
else if(IN[2])
OUT = 4'b0010;
else if(IN[1])
OUT = 4'b0001;
else if(IN[0])
OUT = 4'b0000;
else // 什麼都沒有檢測到
OUT = 4'b1111; // 輸出值可自定義,不和上面的輸出值混淆即可
end
endmodule
2、模擬RTL圖
四、4-16譯碼器
1、實現程式碼舉例
module top( IN,OUT);
input [3:0] IN;
output[15:0] OUT;
reg [15:0] OUT;
always @ (IN) begin
case(IN)
4'b0000: OUT = 16'b0000000000000001;
4'b0001: OUT = 16'b0000000000000010;
4'b0010: OUT = 16'b0000000000000100;
4'b0011: OUT = 16'b0000000000001000;
4'b0100: OUT = 16'b0000000000010000;
4'b0101: OUT = 16'b0000000000100000;
4'b0110: OUT = 16'b0000000001000000;
4'b0111: OUT = 16'b0000000010000000;
4'b1000: OUT = 16'b0000000100000000;
4'b1001: OUT = 16'b0000001000000000;
4'b1010: OUT = 16'b0000010000000000;
4'b1011: OUT = 16'b0000100000000000;
4'b1100: OUT = 16'b0001000000000000;
4'b1101: OUT = 16'b0010000000000000;
4'b1110: OUT = 16'b0100000000000000;
4'b1111: OUT = 16'b1000000000000000;
// full case 不需要寫default,否則一定要有default
endcase
end
endmodule
2、模擬RTL圖
輸入序列位數越大,模擬的資源開銷越大
五、加法器
1、無符號加法器
(1)實現程式碼舉例(四輸入四輸出)
module top( IN1,IN2,OUT);
input[3:0] IN1, IN2;
output[3:0] OUT;
reg[3:0] OUT;
[email protected](IN1 or IN2) begin // 生成組合邏輯的always 塊
OUT = IN1 + IN2;
end
endmodule
(2)模擬波形圖
如果增加輸入位數,波形延遲也將增加,一旦輸出超出給定的位寬,波形將從最低位開始顯示,高位將顯示不了。
2、有符號加法器
(1)實現程式碼舉例(四輸入四輸出)
module top( IN1 ,IN2 , OUT );
input signed [3:0] IN1, IN2;
output signed [3:0] OUT;
reg signed [3:0] OUT;
[email protected](IN1 or IN2) begin // 生成組合邏輯的always 塊
OUT = IN1 + IN2;
end
endmodule
(2)模擬波形圖
3、帶流水線的加法器
(1)實現程式碼舉例(八輸入五輸出,含兩級流水線)
module top( IN1 ,IN2 ,CLK ,OUT );
input [7:0] IN1, IN2;
input CLK;
output [4:0] OUT;
reg [7:0] in1_d1R, in2_d1R,in11_d1R, in22_d1R;
reg [4:0] adder_out1,OUT;
[email protected](posedge CLK) begin // 生成D觸發器的always塊
in1_d1R <= IN1;
in2_d1R <= IN2;
in11_d1R <= in1_d1R;
in22_d1R <= in2_d1R;
OUT <= adder_out1;
end
[email protected](in11_d1R or in22_d1R) begin // 生成組合邏輯的always 塊
adder_out1=in11_d1R+in22_d1R;
end
endmodule
(2)模擬RTL圖
(3)模擬波形圖
和不帶流水線的加法器相比,毛刺的時間長度變短變少,因為加入的D觸發器使得對應的輸入和輸出同步起來,總體輸出晚了四個時鐘。輸入資料和其對應的結果不在一個時鐘週期。
六、帶流水線的無符號乘法器
1、實現程式碼舉例
module top( IN1 , IN2 ,CLK , OUT );
input [3:0] IN1, IN2;
input CLK ;
output [7:0] OUT;
reg [3:0] in1_d1R, in2_d1R;
reg [7:0] adder_out, OUT;
[email protected](posedge CLK) begin // 生成D觸發器的always塊
in1_d1R <= IN1;
in2_d1R <= IN2;
OUT <= adder_out;
end
[email protected](in1_d1R or in2_d1R) begin // 生成組合邏輯的always 塊
adder_out = in1_d1R * in2_d1R;
end
endmodule
2、模擬RTL圖
3、模擬波形圖
沒有硬體乘法器的FPGA晶片編譯之後的資源開銷遠遠增大。和不帶流水線的乘法器相比,毛刺的時間長度變短變少,因為加入的D觸發器使得對應的輸入和輸出同步起來,總體輸出晚了3個時鐘。輸入資料和其對應的結果不在一個時鐘週期。