一、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;
always@(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;
always@(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;
always@(posedge CLK) begin // 生成D触发器的always块
in1_d1R <= IN1;
in2_d1R <= IN2;
in11_d1R <= in1_d1R;
in22_d1R <= in2_d1R;
OUT <= adder_out1;
end
always@(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;
always@(posedge CLK) begin // 生成D触发器的always块
in1_d1R <= IN1;
in2_d1R <= IN2;
OUT <= adder_out;
end
always@(in1_d1R or in2_d1R) begin // 生成组合逻辑的always 块
adder_out = in1_d1R * in2_d1R;
end
endmodule
2、仿真RTL图
3、仿真波形图
没有硬件乘法器的FPGA芯片编译之后的资源开销远远增大。和不带流水线的乘法器相比,毛刺的时间长度变短变少,因为加入的D触发器使得对应的输入和输出同步起来,总体输出晚了3个时钟。输入数据和其对应的结果不在一个时钟周期。
七、计数器
1、实现代码举例
module top(
RST , // 异步复位, 高有效in
CLK , // 时钟,上升沿有效in
EN , // 输入的计数使能,高有效
CLR , // 输入的清零信号,高有效
LOAD , // 输入的数据加载使能信号,高有效
DATA , // 输入的加载数据信号
CNTVAL,
cnt_next, // 输出的计数值信号
OV );// 计数溢出信号,计数值为最大值时该信号为1
input RST , CLK , EN , CLR , LOAD ;
input [3:0] DATA ;
output [3:0] CNTVAL,cnt_next;
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//1
if(CLR)
begin // 清零有效
cnt_next=0;
end
else
begin//clr wuxiao
if(EN)
begin //en youxiao
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//load wuxiao
end //en youxiao
else
begin // 使能无效,计数值保持不动
cnt_next = CNTVAL;
end // else EN wuxiao
end //clr wuxiao
end //1
// 时序逻辑 更新下一时钟周期的计数值
// 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
2、仿真RTL图
该计数器带有多种信号,其中同步清零CLR的优先级最高,使能EN次之,LOAD最低。
八、状态机
设计一个用于识别2进制序列“1011”的状态机,电路每个时钟周期输入1比特数据,当捕获到1011的时钟周期,电路输出1,否则输出0,给电路添加输入使能端口,只有输入使能EN为1的时钟周期,才从输入的数据端口向内部获取1比特序列数据。
1、实现代码举例
module top(
CLK , // clock
RST ,
EN , // reset
CENT1IN , // input 1 cent coin
TINOUT ); // output 1 tin cola
input CLK ;
input RST ,EN ;
input CENT1IN ;
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 ;
// calc next state
always @ (CENT1IN or stateR or EN)
begin
if(EN)
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_0_CENT ; else next_state = ST_3_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
if(stateR == ST_4_CENT)
begin
TINOUT = 1'b1;
end
else
begin
TINOUT = 1'b0;
end
end
else //en
begin
next_state = ST_0_CENT;
end
end
always @ (posedge CLK or posedge RST)begin
if(RST)
stateR <= ST_0_CENT;
else
stateR <= next_state;
end
endmodule
2、仿真波形图
九、移位寄存器
带加载使能和移位使能的并入串出的移位寄存器
1、实现代码举例
module top(
RST , // 异步复位, 高有效
LOAD ,
CLK , // 时钟,上升沿有效
EN , // 输入数据串行移位使能
IN ,
// 输入串行数据
OUT ); // 并行输出数据
input RST, CLK, EN,LOAD;
input [3:0] IN;
output OUT;
reg OUT;
reg [2:0] shift_R;
always @ (posedge CLK or posedge RST )
begin//1
if(RST)
begin//2
shift_R[2:0] <= 0;
OUT <= 0;
end //2
else //RST
begin//3
if(EN)
begin
// shift_RD[3:0] <= IN[3:0] ;
// begin
if(LOAD)
begin
OUT <= IN[3];
shift_R[2:0] <= IN[2:0];
end
else begin // 使能无效保持不动
OUT <= shift_R[2];
shift_R[2:1] <= shift_R[1:0];
shift_R[0] <= 0;
end
end//8
//end//
else//EN
begin//5
shift_R[2:0] <= shift_R[2:0];
OUT <= OUT;
end
end
end
endmodule
2、仿真RTL图
3、仿真波形图