Verilog新手上路學生實驗
阿新 • • 發佈:2018-11-09
MUX41
verilog程式碼:
// module top, 選擇器(mux)的程式碼, module top( IN0 , // input 1 IN1 , // input 2 IN2 , // input 3 IN3 , // input 4 S0 , // select S1 , OUT ); // out data input IN0,IN1,IN2,IN3;// 選擇器的四個輸入資料訊號 input S0,S1; output OUT; // 選擇器的輸出資料訊號 reg OUT; // 生成組合邏輯的程式碼 always @ (IN0 or IN1 or IN2 or IN3 or S0 or S1) begin case({S1,S0}) 2'b00:OUT<=IN0; 2'b01:OUT<=IN1; 2'b10:OUT<=IN2; 2'b11:OUT<=IN3; default: OUT<=IN0; endcase end endmodule // endmodule top
RTL檢視:
Flow Summary
4x4 crossbar switch circuit
verilog程式碼:
// module top, a 4x4 crossbar switch circuit module top( IN0 , // input 1 IN1 , // input 2 IN2 , // input 3 IN3 , // input 4 SEL0 , // select the output0 source SEL1 , // select the output1 source SEL2 , // select the output2 source SEL3 , // select the output3 source OUT0 , // output data 0 OUT1 , // output data 1 OUT2 , // output data 2 OUT3 ); // output data 3 parameter WL = 16; input [WL-1:0] IN0,IN1,IN2,IN3; input SEL0,SEL1,SEL2,SEL3; output[WL-1:0] OUT0,OUT1,OUT2,OUT3; reg [WL-1:0] OUT0,OUT1,OUT2,OUT3; // get the OUT0 always @ (IN0 or IN1 or IN2 or IN3 or SEL0 or SEL1) begin if((SEL0)&&(SEL1)) OUT0 = IN3; else if((!SEL0)&&(SEL1)) OUT0 = IN2; else if((SEL0)&&(!SEL1)) OUT0 = IN1; else OUT0 = IN0; end // get the OUT1 always @ (IN0 or IN1 or IN2 or IN3 or SEL1 or SEL2) begin if((SEL1)&&(SEL2)) OUT1 = IN3; else if((!SEL1)&&(SEL2)) OUT1 = IN2; else if((SEL1)&&(!SEL2)) OUT1 = IN1; else OUT1 = IN0; end // get the OUT2 always @ (IN0 or IN1 or IN2 or IN3 or SEL2 or SEL3) begin if((SEL2)&&(SEL3)) OUT2 = IN3; else if((!SEL2)&&(SEL3)) OUT2 = IN2; else if((SEL2)&&(!SEL3)) OUT2 = IN1; else OUT2 = IN0; end // get the OUT3 always @ (IN0 or IN1 or IN2 or IN3 or SEL3 or SEL0) begin if((SEL3)&&(SEL0)) OUT3 = IN3; else if((!SEL3)&&(SEL0)) OUT3 = IN2; else if((SEL3)&&(!SEL0)) OUT3 = IN1; else OUT3 = IN0; end endmodule // endmodule top
RTL 檢視:
Flow Summary
優先編碼器
// module top, 8 input priority encoder with zero input check module top( IN , // input OUT ); // output input [7:0] IN; output[3:0] OUT; reg [3:0] OUT; // get the 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
RTL檢視:
4_16譯碼器
verilog 程式碼
module top(
IN , // input
OUT ); // output
input [3:0] IN;
output[15:0] OUT;
reg [15:0] OUT;
// get the 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
RTL檢視:
Flow Summary
無符號加法器
4輸入4輸出無符號加法器
可見輸出等於輸入相加。
8輸入5輸出無符號加法器
可見其輸出時延稍大於4輸入的無符號加法器。
補碼加法器
4輸入4輸出補碼加法器
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
8輸入5輸出補碼加法器
module top(
IN1 ,
IN2 ,
OUT );
input signed [7:0] IN1, IN2;
output signed [7:0] OUT;
reg signed [4:0] OUT;
[email protected](IN1 or IN2) begin // 生成組合邏輯的always 塊
OUT = IN1 + IN2;
end
endmodule
帶流水線的加法器
8輸入5輸出帶流水線加法器
module top(
IN1 ,
IN2 ,
CLK ,
OUT );
input [7:0] IN1, IN2;
input CLK;
output [4:0] OUT;
reg [7:0] in1_d1R, in2_d1R;
reg [4: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
二級流水線加法器
module top(
IN1 ,
IN2 ,
CLK ,
OUT );
input [7:0] IN1, IN2;
input CLK;
output [4:0] OUT;
reg [7:0] in1_d1R, in2_d1R,in1_d2R, in2_d2R;
reg [4:0] adder_out, OUT;
[email protected](posedge CLK) begin // 生成D觸發器的always塊
in1_d1R <= IN1;
in2_d1R <= IN2;
in1_d2R <= in1_d1R;
in2_d2R <= in2_d1R;
OUT <= adder_out;
end
[email protected](in1_d1R or in2_d1R) begin // 生成組合邏輯的always 塊
adder_out = in1_d2R + in2_d2R;
end
endmodule
乘法器
8輸入8輸出乘法器
//////////////////// 有符號的補碼乘法器 /////////////////////////
module top(
IN1 ,
IN2 ,
OUT );
input signed[7:0] IN1, IN2;
output signed [7:0] OUT;
reg signed[7:0] OUT;
[email protected](IN1 or IN2) begin // 生成組合邏輯的always 塊
OUT = IN1 * IN2;
end
endmodule
流水線乘法器
//////////////////// 流水線乘法器 /////////////////////////
module top(
IN1 ,
IN2 ,
CLK ,
OUT );
input signed[3:0] IN1, IN2;
input CLK;
output signed [7:0] OUT;
reg signed[7:0] mul_out,OUT;
reg signed[3:0] in1_dlr,in2_dlr;
[email protected](posedge CLK) begin
in1_dlr <= IN1;
in2_dlr <= IN2;
OUT <= mul_out;
end
[email protected](in1_dlr or in2_dlr) begin
mul_out = in1_dlr * in2_dlr;
end
endmodule
計數器
簡單計數器
//////////////////// 計數器程式碼 /////////////////////////
module top(
CLK , // 時鐘,上升沿有效
OV );// 計數溢位訊號,計數值為最大值時該訊號為1
input CLK ;
output OV;
reg [3:0] cnt_next;
reg OV;
// 電路編譯引數,最大計數值
// 組合邏輯,生成cnt_next
parameter CNT_MAX_VAL =7;
always @ (posedge CLK ) begin
if(cnt_next<CNT_MAX_VAL) begin
OV <= 0;
cnt_next <= cnt_next+1;
end
else begin
OV <= 1;
cnt_next <= 0;
end
end
endmodule
複雜計數器
//////////////////// 計數器程式碼 /////////////////////////
module top(
RST , // 非同步復位, 高有效
CLK , // 時鐘,上升沿有效
EN , // 輸入的計數使能,高有效
CLR , // 輸入的清零訊號,高有效
LOAD , // 輸入的資料載入使能訊號,高有效
DATA , // 輸入的載入資料訊號
CNTVAL, // 輸出的計數值訊號
OV );// 計數溢位訊號,計數值為最大值時該訊號為1
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;
// 組合邏輯,生成cnt_next
// 計數使能最優先,清零第二優先,載入第三優先
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 // 未計數到最大值, 下一值加1
cnt_next = CNTVAL + 1'b1;
end
else begin // 計數到最大值,下一計數值為0
cnt_next = 0;
end
end // else LOAD
end // else EN
else begin // 清零無效,計數值保持不動
cnt_next = CNTVAL;
end // else EN
end
end
// 時序邏輯 更新下一時鐘週期的計數值
// CNTVAL 會被編譯為D觸發器
always @ (posedge CLK or posedge RST) begin
if(RST)
CNTVAL <= 0;
else
CNTVAL <= cnt_next;
end
// 組合邏輯,生成OV
always @ (CNTVAL) begin
if(CNTVAL == CNT_MAX_VAL)
OV = 1;
else
OV = 0;
end
endmodule
狀態機
基本要求的識別序列1011的狀態機
module top(
CLK , // clock
RST , // reset
//EN ,
IN ,
OUT );
input CLK , RST ;// EN ;
input IN ;
output OUT ;
parameter ST_State0 = 0;
parameter ST_State1 = 1;
parameter ST_State2 = 2;
parameter ST_State3 = 3;
parameter ST_State4 = 4;
reg [4:0]stateR ;
reg [4:0]next_state ;
reg OUT ;
always @ (IN or stateR ) begin//or EN
// if(EN)begin
case (stateR)
ST_State0 :begin if(IN) next_state =ST_State1 ; else next_state = ST_State0; end
ST_State1 :begin if(IN) next_state =ST_State1 ; else next_state = ST_State2; end
ST_State2 :begin if(IN) next_state =ST_State3 ; else next_state = ST_State0; end
ST_State3 :begin if(IN) next_state =ST_State4 ; else next_state = ST_State2; end
ST_State4 :begin next_state = ST_State0;end
endcase
//end
//else
// if(next_state!=ST_State0)
// next_state=stateR;
end
always @ (stateR) begin
if(stateR == ST_State4)
OUT = 1;
else
OUT = 0;
end
always @ (posedge CLK or posedge RST)begin
if(RST)
stateR <= ST_State0;
else
stateR <= next_state;
end
endmodule
帶使能端的識別序列1011的狀態機
module top(
CLK , // clock
RST , // reset
EN ,
IN ,
OUT );
input CLK , RST ,EN ;
input IN ;
output OUT ;
parameter ST_State0 = 0;
parameter ST_State1 = 1;
parameter ST_State2 = 2;
parameter ST_State3 = 3;
parameter ST_State4 = 4;
reg [4:0]stateR ;
reg [4:0]next_state ;
reg OUT ;
always @ (IN or stateR or EN ) begin
if(EN)begin
case (stateR)
ST_State0 :begin if(IN) next_state =ST_State1 ; else next_state = ST_State0; end
ST_State1 :begin if(IN) next_state =ST_State1 ; else next_state = ST_State2; end
ST_State2 :begin if(IN) next_state =ST_State3 ; else next_state = ST_State0; end
ST_State3 :begin if(IN) next_state =ST_State4 ; else next_state = ST_State2; end
ST_State4 :begin next_state = ST_State0;end
endcase
end
else
if(next_state!=ST_State0)
next_state=stateR;
end
always @ (stateR) begin
if(stateR == ST_State4)
OUT = 1;
else
OUT = 0;
end
always @ (posedge CLK or posedge RST)begin
if(RST)
stateR <= ST_State0;
else
stateR <= next_state;
end
endmodule
移位暫存器
//////////////////// 併入串出移位暫存器 /////////////////////////
module top(
RST , // 非同步復位, 高有效
CLK , // 時鐘,上升沿有效
EN , // 輸入資料序列移位使能
IN , // 輸入序列資料
LOAD ,
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] <= IN;
end
else begin
shift_R[3:0] <= shift_R[3:0];
end
end
end
end // always
endmodule