概述
文章目录
- 1. 计数器
- 2. 分频器
- 3. 状态机
- 3.1 Moore状态机(摩尔)
- 3.2 Mealy状态机(米利)
- 4. 序列检测器
- 4.1 状态机描述
- 4.2 移位寄存器
- 5. 序列生成器
- 6. 伪随机码发生器
- 7. 异步复位,同步释放
- 8. 超前进位加法器
- 9. FIR滤波器
- 10. 自动售卖机
- 11. 红绿灯
- 12. 格雷码计数器
- 13. 并串转换
- 14. 串并转换
- 14. 同步FIFO
- 15. 异步FIFO
!!! 务必搞清楚每一个设计的输入和输出信号 !!!<mark>
1. 计数器
计数器
2. 分频器
分频器
3. 状态机
关于摩尔型状态机与米利型状态机的区别
3.1 Moore状态机(摩尔)
摩尔型状态机:输出只取决于当前状态,与输入无直接关系。
3.2 Mealy状态机(米利)
米利型:输出取决于当前状态和输入。
摩尔型和米利型状态机的对比:
1)摩尔型更安全。
输出在时钟边沿变化(总是在一个周期后)。在Mealy机器中,输入更改可能会在逻辑完成后立即导致输出更改, 当两台机器互连时出现大问题 - 如果不小心,可能会发生异步反馈。
2)Mealy机器对输入的反应更快
在相同的周期内反应 - 不需要等待时钟。 在Moore机器中,可能需要更多逻辑来将状态解码为输出 - 在时钟边沿之后更多的门延迟。
并非所有时序电路都可以使用Mealy模型实现。 一些时序电路只能作为摩尔机器实现。
3)对于同一个设计来说,米利型的状态少,减少资源的消耗。但是各个状态间的状态跳转更复杂。
4. 序列检测器
4.1 状态机描述
状态机描述_序列检测器
next_state另一种写法
这个有电路图
4.2 移位寄存器
移位寄存器_序列检测器
这个带仿真图
两种方法的对比:
1)跟用状态机实现的区别在于,使用移位寄存器需要存储所有的码字,因此如果序列长度为N,则该方法需要消耗的寄存器就是N个。而使用状态机实现时,每个状态代表部分码字,如果使用十进制编码,则只需要使用log2(N)个寄存器即可编码所有状态,从寄存器资源的角度来看FSM实现起来代价较小。
2)此外,寄存器版本每来一个码元都要比较所有码字,因此需要消耗N个比较器,而FSM的的状态寄存器每一位在状态转移时都需要不同的译码逻辑,如果状态转移比较简单,组合逻辑可能会比移位寄存器少,状态转移复杂的话就不好说了。
3)当然,移位寄存器的版本编码更加简洁明了。
5. 序列生成器
生成序列01011011101111…依次类推
生成序列01011011101111
思路:有2个0的时候有2个1,有3个0的时候有3个1…
循环产生序列信号001011
移位寄存器方法除了可以有一个输入序列的接口,还可以在初始化时将序列填入移位寄存器中。代码如下:
产生序列信号11010111
module seq_gen(
input clk,
input rst_n,
output seq );
reg [7:0]out_seq;
always@(posedge clk or negedge rst_n)
if(!rst_n) out_seq <= 8'b11010111;
else out_seq <= {out_seq[6:0],out_seq[7]};
assign seq = out_seq[7];
6. 伪随机码发生器
4级伪随机码发生器
模运算
7. 异步复位,同步释放
异步复位,同步释放
8. 超前进位加法器
半加器和的输出=A和B的异或;
图源
module half_adder(
input a,
input b,
output sum,
output c_out
);
assign sum = a^b;
assign cout = a&b;
endmodule
全加器和的输出=A、B、C的异或。
图源
module full_adder(
//输入信号,ain表示被加数,bin表示加数,cin表示低位向高位的进位
input ain,bin,cin,
//输出信号,cout表示向高位的进位,sum表示本位的相加和
output reg cout,sum
);
reg s1,s2,s3;
always @(ain or bin or cin) begin
sum=(ain^bin)^cin;//本位和输出表达式
s1=ain&cin;
s2=bin&cin;
s3=ain&bin;
cout=(s1|s2)|s3;//高位进位输出表达式
end
endmodule
两个半加器可以构成一个全加器。
将多个“一位全加器”级联起来,可以变成“多位全加器”,上一个全加器的“进位输出”连到下一个全加器的“进位输入”。比如8位全加器如下:
图源
级联多位全加器高位需要低位的进位位,故位宽增大时,加法的组合逻辑不断增大,延时非常大,超前进位加法器解决了这一问题。
超前进位加法器 (Carry-Lookahead Adder,CLA)是高速加法器,每一级进位有附加的组合电路产生。高位的运算不需要地位的等待,因此速度很高。
数字电路基础知识(四) 加法器-半加器、全加器与超前进位加法器
多位超前进位加法器
以全加器代码为例说明门级,数据流级,行为级建模的区别
- 数据流建模,一般用assign声明描述电路行为(连续赋值语句。因此这里的输出必须设置成wire类型)
- 行为级建模,一般用initial 或者always (过程连续赋值语句,因为这里有always,输出必须设置成reg类型的)
9. FIR滤波器
10. 自动售卖机
自动贩售机米利型_B站视频_FPGA探索者
自动贩售机摩尔型_B站视频
- 状态机实现方式
请设计状态机电路,实现自动售卖机功能,A饮料5元钱,B饮料10元钱,售卖机可接收投币5元钱和10元钱,每次投币只可买一种饮料,考虑找零的情况。
FPGA开发/数字IC求职系列(刷题篇)(8)——牛客网Verilog企业真题01哲K
`timescale 1ns/1ns
module sale(
input clk ,
input rst_n ,
input sel ,//sel=0,5$dranks,sel=1,10&=$drinks
input [1:0] din ,//din=1,input 5$,din=2,input 10$
output reg [1:0] drinks_out,//drinks_out=1,output 5$ drinks,drinks_out=2,output 10$ drinks
output reg change_out
);
parameter IDLE = 2'b01,
B_5 = 2'b10;
reg [1:0] curr_state;
reg [1:0] next_state;
always@(posedge clk or negedge rst_n)begin
if(~rst_n)
curr_state <= IDLE;
else
curr_state <= next_state;
end
always@(*)
if(~rst_n)
next_state <= IDLE;
else begin
case(curr_state)
IDLE:
begin
case({sel,din})
3'b101:next_state <= B_5;
default:next_state <= IDLE;
endcase
end
B_5 :
begin
case({sel,din})
3'b100:next_state <= B_5;
default:next_state <= IDLE;
endcase
end
default:next_state <= IDLE;
endcase
end
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
drinks_out <= 2'd0;
change_out <= 1'b0;
end
else begin
case(curr_state)
IDLE:
begin
case({sel,din})
3'b001:begin drinks_out <= 2'd1;change_out <= 1'b0; end
3'b010:begin drinks_out <= 2'd1;change_out <= 1'b1; end
3'b110:begin drinks_out <= 2'd2;change_out <= 1'b0; end
default:begin drinks_out <= 2'd0;change_out <= 1'b0; end
endcase
end
B_5:
begin
case({sel,din})
3'b101:begin drinks_out <= 2'd2;change_out <= 1'b0; end
3'b110:begin drinks_out <= 2'd2;change_out <= 1'b1; end
default:begin drinks_out <= 2'd0;change_out <= 1'b0; end
endcase
end
default:
begin
drinks_out <= 2'd0;
change_out <= 1'b0;
end
endcase
end
end
endmodule
- 输入金额累加判断
设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。
ps:投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号,注意rst为低电平复位
11. 红绿灯
12. 格雷码计数器
13. 并串转换
并串转换
14. 串并转换
https://blog.csdn.net/vivid117/article/details/102021707
- 利用移位寄存器
module serial_parallel(
input clk,
input rst_n,en,
input data_i, //一位输入
output reg [7:0] data_o //8位并行输出
);
always @(posedge clk or negedge rst_n) begin
if (rst_n == 1'b0)
data_o <= 8'b0;
else if (en == 1'b1)
data_o <= {data_o[6:0], data_i}; //低位先赋值
//data_o <= {data_i,data_o[7:1],}; //高位先赋值
else
data_o <= data_o;
end
endmodule
- 利用计数器
module serial_parallel(
input clk,
input rst_n,
input data_i,
output reg [7:0] data_o
);
//msb first most significant bit 表示二进制数据的最高位
reg [2:0] cnt; //计数器0-7
always @(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
data_o <= 8'b0;
cnt <= 3'd0;
end
else begin
data_o[7 - cnt] <= data_i; 高位先赋值
cnt <= cnt + 1'b1;
end
end
/*
//lsb first (least significant bit) 表示二进制数据的最低位
reg [2:0] cnt;
always @(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
data_o <= 8'b0;
cnt <= 3'd0;
end
else begin
data_o[cnt] <= data_i; //低位先赋值
cnt <= cnt + 1'b1;
end
end
*/
endmodule
14. 同步FIFO
15. 异步FIFO
改变字体颜色:
浅红色文字:浅红色文字:
深红色文字:深红色文字
浅绿色文字:浅绿色文字
深绿色文字:深绿色文字
改变字体大小:
size为1:size为1
size为2:size为2
size为10:size为10
改变字体背景:
背景色的设置是按照十六进制颜色值:#7FFFD4 |
背景色的设置是按照十六进制颜色值:#FF83FA |
背景色的设置是按照十六进制颜色值:#D1EEEE |
背景色的设置是按照十六进制颜色值:#C0FF3E |
背景色的设置是按照十六进制颜色值:#54FF9F |
改变字体:
我是黑体字
我是宋体字
我是微软雅黑字
我是fantasy字
我是Helvetica字
最后
以上就是调皮巨人为你收集整理的手撕代码汇总1. 计数器2. 分频器3. 状态机4. 序列检测器5. 序列生成器6. 伪随机码发生器7. 异步复位,同步释放8. 超前进位加法器9. FIR滤波器10. 自动售卖机11. 红绿灯12. 格雷码计数器13. 并串转换14. 串并转换14. 同步FIFO15. 异步FIFO的全部内容,希望文章能够帮你解决手撕代码汇总1. 计数器2. 分频器3. 状态机4. 序列检测器5. 序列生成器6. 伪随机码发生器7. 异步复位,同步释放8. 超前进位加法器9. FIR滤波器10. 自动售卖机11. 红绿灯12. 格雷码计数器13. 并串转换14. 串并转换14. 同步FIFO15. 异步FIFO所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复