进阶项目(1)字符状态机

写在前面的话

作为一个电子男,一直被女孩子认为是刻板、不懂浪漫的,其实不然,我们可以以我们独特的方式来表达我们的浪漫情怀。这一节,梦翼师兄就用我们电子男特有的方式对我们最亲爱的人说一声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

1920行的代码解释:在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!”,说明我们的设计正确。

 

猜你喜欢

转载自www.cnblogs.com/mengyi1989/p/11517627.html