FPGA作業.2
阿新 • • 發佈:2018-12-20
2、關於4X4交叉開關 在已有程式碼的基礎上進行了修改
module mux44(in0,in1,in2,in3,out0,out1,out2,out3,sl0,sl1,sl2,sl3); parameter WL = 16; input [WL-1:0] in0,in1,in2,in3; input sl0,sl1,sl2,sl3; output[WL-1:0] out0,out1,out2,out3; reg [WL-1:0] out0,out1,out2,out3; always @ (in0 or in1 or in2 or in3 or out0 or sl0 or sl1) begin if((sl0)&&(sl1)) out0=in3; else if((!sl0)&&(sl1)) out0=in2; else if((sl0)&&(!sl1)) out0=in1; else out0=in0; end always @ (in0 or in1 or in2 or in3 or out1 or sl1 or sl2) begin if((sl1)&&(sl2)) out1=in3; else if((!sl1)&&(sl2)) out1=in2; else if((sl1)&&(!sl2)) out1=in1; else out1=in0; end always @ (in0 or in1 or in2 or in3 or out2 or sl2 or sl3) begin if((sl2)&&(sl3)) out2=in3; else if((!sl2)&&(sl3)) out2=in2; else if((sl2)&&(!sl3)) out2=in1; else out2=in0; end always @ (in0 or in1 or in2 or in3 or out3 or sl0 or sl3) begin if((sl0)&&(sl3)) out3=in3; else if((!sl0)&&(sl3)) out3=in2; else if((sl0)&&(!sl3)) out3=in1; else out3=in0; end endmodule
下面是進行編譯之後的資源消耗的顯示。上圖為4X4,下圖是2X2的顯示: 編譯之後,RTL view如下圖所示: 3、這題為做一個8位優先選擇器,程式碼相對簡單,如下面展示:
module YX( IN , OUT ); input [7:0] IN; output[3:0] OUT; reg [3:0] OUT; always @ (IN) begin if(IN[7]) OUT = 3'b0111; else if(IN[6]) OUT = 3'b0110; else if(IN[5]) OUT = 3'b0101; else if(IN[4]) OUT = 3'b0100; else if(IN[3]) OUT = 3'b0011; else if(IN[2]) OUT = 3'b0010; else if(IN[1]) OUT = 3'b0001; else if(IN[0]) OUT = 3'b0000; else OUT = 3'b1111; end endmodule
編譯之後,觀看RTL View.如圖
4、關於38譯碼器和416譯碼器 關於416譯碼器的程式碼的編寫,也是在38譯碼器的基礎上進行修改。
module yiima416( IN , OUT ); input [3:0] IN; output[15:0] OUT; reg [15:0] OUT; always @ (IN) begin case(IN) 4'b0000: OUT = 16'b0000_0000_0000_0001; 4'b0001: OUT = 16'b0000_0000_0000_0010; 4'b0010: OUT = 16'b0000_0000_0000_0100; 4'b0011: OUT = 16'b0000_0000_0000_1000; 4'b0100: OUT = 16'b0000_0000_0001_0000; 4'b0101: OUT = 16'b0000_0000_0010_0000; 4'b0110: OUT = 16'b0000_0000_0100_0000; 4'b0111: OUT = 16'b0000_0000_1000_0000; 4'b1000: OUT = 16'b0000_0001_0000_0000; 4'b1001: OUT = 16'b0000_0010_0000_0000; 4'b1010: OUT = 16'b0000_0100_0000_0000; 4'b1011: OUT = 16'b0000_1000_0000_0000; 4'b1100: OUT = 16'b0001_0000_0000_0000; 4'b1101: OUT = 16'b0010_0000_0000_0000; 4'b1110: OUT = 16'b0100_0000_0000_0000; 4'b1111: OUT = 16'b1000_0000_0000_0000; endcase end endmodule
然後進行編譯,可以看到38和416的資源消耗是差一倍的。 38譯碼的資源消耗 416譯碼的資源消耗 然後可以看一下416的RTL View:
5、無符號加法器 只放一下8輸入的加法器的程式碼圖
module addunsign(
IN1 ,
IN2 ,
OUT );
input[7:0] IN1, IN2;
output[4:0] OUT;
reg[4:0] OUT;
[email protected](IN1 or IN2) begin
OUT = IN1 + IN2;
end
endmodule
加法器中輸出改為4位元的模擬圖 可以看到當輸出的結果超出了輸出所能表示的時候,會出現結果和想象的不一樣. 輸入為8位的時候的模擬圖 可以 看到輸出的結果的延遲是是比4輸入的時候的延遲要大一些的 。
後面是有符號的加法器和流水線加法器
6、計數器 只有clk輸入和OV輸出的計數器,其程式碼如下:
module count1( clk, ov);
input clk;
output ov;
reg [3:0] cnt_next;
reg ov;
parameter CNT_MAX_VAL = 9;
always @ (posedge clk) begin
if(cnt_next < CNT_MAX_VAL) begin
ov=0;
cnt_next = cnt_next + 1'b1;
end
else begin
ov=1;
cnt_next = 0;
end
end
endmodule
模擬結果如下: 可以看到當計數到10的時候就會計1,然後接著計數
然後是相對複雜的一個計數器
module cntcom(
RST ,
CLK ,
EN ,
CLR ,
LOAD ,
DATA ,
CNTVAL,
OV );
input RST , CLK , EN , CLR , LOAD ;
input [3:0] DATA ;
output [3:0] CNTVAL;
output OV;
reg [3:0] CNTVAL, cnt_next;
reg OV;
parameter CNT_MAX_VAL = 9;
always @(EN or CLR or LOAD or DATA or CNTVAL) begin
if(CLR) begin
cnt_next = 0;
end
else begin
if(EN) begin
if(LOAD) begin
cnt_next = DATA;
end
else begin
if(CNTVAL < CNT_MAX_VAL) begin
cnt_next = CNTVAL + 1'b1;
end
else begin
cnt_next = 0;
end
end
end
else begin
cnt_next = CNTVAL;
end
end
end
always @ (posedge CLK or posedge RST) begin
if(RST)
CNTVAL <= 0;
else
CNTVAL <= cnt_next;
end
always @ (CNTVAL) begin
if(CNTVAL == CNT_MAX_VAL)
OV = 1;
else
OV = 0;
end
endmodule
波形模擬圖如下
7、狀態機 程式碼如下
module yiwei(
CLK ,
EN ,
RST ,
CENT1IN ,
TINOUT );
input CLK ;
input RST ;
input CENT1IN ;
input EN ;
output TINOUT ;
parameter ST_0_CENT = 0;
parameter ST_1_CENT = 1;
parameter ST_2_CENT = 2;
parameter ST_3_CENT = 3;
parameter ST_4_CENT = 4;
reg [4-2:0]stateR ;
reg [4-2:0]next_state ;
reg TINOUT ;
always @ (CENT1IN or stateR) begin
case (stateR)
ST_0_CENT :begin if(CENT1IN) next_state = ST_1_CENT ; else next_state = ST_0_CENT; end
ST_1_CENT :begin if(CENT1IN) next_state = ST_2_CENT ; else next_state = ST_0_CENT; end
ST_2_CENT :begin if(!CENT1IN) next_state = ST_3_CENT ; else next_state = ST_0_CENT; end
ST_3_CENT :begin if(CENT1IN) next_state = ST_4_CENT ; else next_state = ST_0_CENT; end
ST_4_CENT :begin next_state = ST_0_CENT ;end
endcase
end
always @ (stateR) begin
if(EN) begin
if(stateR == ST_4_CENT)
TINOUT = 1'b1;
else
TINOUT = 1'b0;
end
end
// state DFF
always @ (posedge CLK or posedge RST)begin
if(RST)
stateR <= ST_0_CENT;
else
stateR <= next_state;
end
endmodule
上面的程式碼是一個帶有EN使能的狀態機,當遇到1011時,輸出為1,否則輸出就為0. 狀態轉移圖也可以通過Tools-Netlist Viewers-State Machine Viewer 看到,如下圖:
模擬結果如下: 當EN為0時,模擬沒有結果 當EN為1時,模擬才可以成功捕獲: 8、併入串出的移位暫存器 程式碼如下圖所以
module crbc(
RST ,
CLK ,
EN ,
LOAD ,
IN ,
OUT );
input RST, CLK, EN, LOAD;
input [3:0]IN;
output OUT;
reg [3:0] shift_R;
reg OUT;
always @ (posedge CLK or posedge RST or posedge LOAD) begin
if(RST)
shift_R[3:0] <= 0;
else begin
if(LOAD) begin
shift_R[3:0] <= IN[3:0];
end
else begin
if(EN) begin
OUT = shift_R[3];
shift_R[3:1] <= shift_R[2:0];
shift_R[0] <= 0;
end
else begin
shift_R[3:0] <= shift_R[3:0];
end
end
end
end
endmodule
RTL View為下圖所示: 模擬結果如下