写在前面的话 作为一个电子男,一直被女孩子认为是刻板、不懂浪漫的,其实不然,我们可以以我们独特的方式来表达我们的浪漫情怀。这一节,梦翼师兄就用我们电子男特有的方式对我们最亲爱的人说一声I Love You!
项目需求 设计一个电路,输入端cap_flow输入的是随机的大写字母数据流,输入端low_flow输入的是随机的小写字母数据流,输出端output_flow输出的是从两个输入字母流中检出的字符所组成的最深情的一句话I Love You!(注:大写字母数据和小写字母的产生方式均是用ASCII值来实现的)
解决方案 状态机通过检测cap_flow端口和low_flow端口的数据流,分11个状态来完成检测,其中8个状态依次捕获“I Love You”中每个字母的ASCII值,每当捕获到相应字符的ASCII值,则将相应字符的ASCII值输出到输出寄存器output_flow,另外3个状态是用于输出I之后空格的ASCII值、Love之后的空格的ASCII值以及You之后的“!”的ASCII值。
系统架构
模块功能介绍 模块名
| 功能描述
| FSM
| 检测出I Love You!
|
顶层模块端口描述 端口名
| 端口说明
| clk
| 系统时钟输入
| rst_n
| 系统复位
| Cap_flow
| 大写字母输入数据流
| Low_flow
| 小写字母输入数据流
| out_flow
| 输出数据流
|
代码解释
FSM模块代码
/****************************************************
* Engineer : 梦翼师兄
* QQ : 761664056
* The module function:检测出I Love You!
*****************************************************/
000 module fsm (
001 clk, //系统输入时钟
002 rst_n, //系统复位
003 cap_flow, //大写字母数据流
004 low_flow, //小写字母数据流
005 out_flow //检测出的字母
006 );
007 // 系统输入
008 input clk;//系统输入时钟
009 input rst_n;//系统复位
010 input [7:0] cap_flow;//大写字母数据流
011 input [7:0] low_flow;//小写字母数据流
012 // 系统输出
013 output reg [7:0] out_flow;//检测出的字母
014 //定义中间寄存器
015 reg [3:0] state;//状态寄存器
016 // 定义十个状态
017 localparam S1 = 4'b0000;
018 localparam S2 = 4'b0001;
019 localparam S3 = 4'b0010;
020 localparam S4 = 4'b0011;
021 localparam S5 = 4'b0100;
022 localparam S6 = 4'b0101;
023 localparam S7 = 4'b0110;
024 localparam S8 = 4'b0111;
025 localparam S9 = 4'b1000;
026 localparam S10 = 4'b1001;
027 localparam S11 = 4'b1010;
028
029 always @ (posedge clk or negedge rst_n)
030 begin
031 if (!rst_n) //复位时,输出空格,状态转移到S1
032 begin
033 out_flow <= " ";
034 state <= S1;
035 end
036 else
037 begin
038 case (state)
039 S1 : begin
040 if (cap_flow == "I")//检测到“I”,转到下一个状态
041 begin
042 out_flow <= cap_flow;
043 state <= S2;
044 end
045 else
046 begin
047 state <= S1;
048 end
049 end
050
051 S2 : begin
052 out_flow <= " ";//输出空格,转到下一个状态
053 state <= S3;
054 end
055
056 S3 : begin
057 if (cap_flow == "L")//检测到“L”,转到下一个状态
058 begin
059 out_flow <= cap_flow;
060 state <= S4;
061 end
062 else
063 begin
064 state <= S3;
065 end
066 end
067
068 S4 : begin
069 if (low_flow == "o")//检测到“o”,转到下一个状态
070 begin
071 out_flow <= low_flow;
072 state <= S5;
073 end
074 else
075 begin
076 state <= S4;
077 end
078 end
079
080 S5 : begin
081 if (low_flow == "v")//检测到“v”,转到下一个状态
082 begin
083 out_flow <= low_flow;
084 state <= S6;
085 end
086 else
087 begin
088 state <= S5;
089 end
090 end
091
092 S6 : begin
093 if (low_flow == "e")//检测到“e”,转到下一个状态
094 begin
095 out_flow <= low_flow;
096 state <= S7;
097 end
098 else
099 begin
100 state <= S6;
101 end
102 end
103
104 S7 : begin//输出空格,转到下一个状态
105 out_flow <= " ";
106 state <= S8;
107 end
108
109 S8 : begin
110 if (cap_flow == "Y")//检测到“Y”,转到下一个状态
111 begin
112 out_flow <= cap_flow;
113 state <= S9;
114 end
115 else
116 begin
117 state <= S8;
118 end
119 end
120
121 S9 : begin
122 if (low_flow == "o")//检测到“o”,转到下一个状态
123 begin
124 out_flow <= low_flow;
125 state <= S10;
126 end
127 else
128 begin
129 state <= S9;
130 end
131 end
132
133 S10 : begin
134 if (low_flow == "u")//检测到“u”,转到下一个状态
135 begin
136 out_flow <= low_flow;
137 state <= S11;
138 end
139 else
140 begin
141 state <= S10;
142 end
143 end
144
145 S11 : begin//输出“!”,转到第一个状态
146 out_flow <= "!";
147 state <= S1;
148 end
149
150 default : state <= S1; //转到第一个状态
151
152 endcase
153 end
154 end
155
156 endmodule
|
/****************************************************
* Engineer : 梦翼师兄
* QQ : 761664056
* The module function:测试fsm模块
*****************************************************/
00 `timescale 1ns/1ps//时间单位和精度定义
01
02 module fsm_tb;
03 //系统输入
04 reg clk;//系统输入时钟
05 reg rst_n;//系统复位
06 reg [7:0] cap_flow; //大写字母数据流
07 reg [7:0] low_flow;//小写字母数据流
08 // 系统输出
09 wire [7:0] out_flow;//检测出的字母
10
11 initial begin
12 clk = 1'b1;
13 rst_n = 1'b0;
14 #200.1
15 rst_n = 1'b1;
16 forever
17 begin
18 #20
19 cap_flow = 65 + {$random}%26; //大写字母数据流
20 low_flow = 97 + {$random}%26;//小写字母数据流
21 end
22 end
23
24 always # 10 clk = ~clk;//50M的时钟
25
26 fsm fsm(
27 .clk(clk), //系统输入时钟
28 .rst_n(rst_n), //系统复位
29 .cap_flow(cap_flow), //大写字母数据流
30 .low_flow(low_flow), //小写字母数据流
31 .out_flow(out_flow)//检测出的字母
32 );
33
34
35 endmodule
|
19和20行的代码解释:在Verilog测试中应用比较广泛的函数 $random,这个函数用于产生一个32位的随机数,它是一个带符号的整形数。下面给大家介绍一下如何用该函数产生某一范围的随机数,$random % a,其中a > 0,它可以产生一个范围为(-a + 1)~ (a - 1) 中的随机数,{$random }% a, 其中a > 0, 它可以产生一个范围为0~ (a - 1) 的随机数。由于英文字母总共有26个,我们可以利用如下语句来产生随机的大写字母流和小写字母流: reg [7:0] cap_flow; //随机大写字母输入 reg [7:0] low_flow; //随机小写字母输入 cap_flow = 65 + {$random} % 26; low_flow = 97 + {$random} % 26; 仿真分析
大写字母数据流和小写字母数据流每个时钟都发生变化,我们设计的系统从大、小写字母的数据流中检测出了 “ I Love You!”,说明我们的设计正确。
【相关课程推荐】 课程名称:梦翼师兄FPGA培训(视频加板卡),手把手带你入门FPGA (有疑问请加客服微信:mlajsw96)
|