我是靠谱客的博主 调皮巨人,这篇文章主要介绍手撕代码汇总1. 计数器2. 分频器3. 状态机4. 序列检测器5. 序列生成器6. 伪随机码发生器7. 异步复位,同步释放8. 超前进位加法器9. FIR滤波器10. 自动售卖机11. 红绿灯12. 格雷码计数器13. 并串转换14. 串并转换14. 同步FIFO15. 异步FIFO,现在分享给大家,希望可以做个参考。

文章目录

  • 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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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的异或;
在这里插入图片描述
图源
在这里插入图片描述

复制代码
1
2
3
4
5
6
7
8
9
10
11
module half_adder( input a, input b, output sum, output c_out ); assign sum = a^b; assign cout = a&b; endmodule

全加器和的输出=A、B、C的异或。
在这里插入图片描述
图源
在这里插入图片描述

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
`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

  1. 利用移位寄存器
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
  1. 利用计数器
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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.内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部