第一次verilog实验——序列检测器的实现

  第一次用verilog上机建模,深刻体会到看书所掌握不到的体会。有时候看书无法细心观察到的东西,在敲实验代码的时候,或许能够体现出来。现将第一次的体会记录如下。

还是先将verilog代码写下

 1 /************************************************************************
 2 模块作者:灰色的鱼
 3 编写时间:13:52 2013/2/13
 4 模块功能:对串行输入的数据流进行检测。只要发现10010序列,就立即输出高电平。
 5 *************************************************************************/
 6 module seqdet(x,z,clk,rst_n);
 7 input clk,rst_n;
 8 input x;
 9 output z;
10 
11 reg z;
12 reg [2:0] pstate,nstate;
13 
14 parameter s1=3'd0,
15           s2=3'd1,
16           s3=3'd2,
17           s4=3'd3,
18           s5=3'd4,
19           s6=3'd5;
20           
21 always @(posedge clk or negedge rst_n)
22 begin
23     if(!rst_n)
24         pstate<=s1;
25     else
26         pstate<=nstate;
27 end
28 
29 always @(pstate or x)
30 begin
31     case(pstate)
32         s1:
33             if(x==1)
34                 nstate=s2;
35             else
36                 nstate=s1;
37         s2:
38             nstate=x?s2:s3;
39         s3:
40             nstate=x?s2:s4;
41         s4:
42             nstate=x?s5:s1;
43         s5:
44             nstate=x?s2:s6;
45         s6:
46             nstate=x?s2:s4;
47         default:
48             nstate=s1;
49         endcase
50 end
51 
52 always @(pstate or x or rst_n)
53 begin
54     if(!rst_n==1)
55         z=1'b0;
56     else if(pstate==s5 && x==0)
57                 z=1'b1;
58          else
59             z=1'b0;
60 end
61 
62 endmodule

然后是testbench的代码:

 1 `timescale 1 ns/ 1 ps
 2 module seqdet_vlg_tst();
 3 
 4 reg clk;
 5 reg rst_n;
 6 wire x;                                             
 7 wire z;
 8 
 9 reg[19:0] data;
10 
11 assign x=data[19];
12                           
13 seqdet i1 (
14   
15     .clk(clk),
16     .rst_n(rst_n),
17     .x(x),
18     .z(z)
19 );
20 
21 initial                                                
22 begin                                                  
23                         
24     clk=0;
25     rst_n=0;
26     #500 rst_n=1; 
27     data=20'b1100_1001_0000_1001_0100;                                                                                              
28     #(100*100) $stop;                     
29 end 
30                                                    
31 always                                                                                                                                        
32     #50 clk=~clk; 
33                                                                                                                                                    
34 always @(posedge clk)
35 begin
36     #2 data={data[18:0],data[19]};
37 end 
38                                                
39 endmodule

用Modelsim进行综合前仿真,波形如下:(波形从上到下依次是clk,rst_n,x,z),x用于序列输入,z为检测到"10010"序列之后的输出。

从第一次实验中得到了几点经验,当然在以后的学习之中还需好好注意:

  1. 写testbench时候,`timescale输入问题,t前面的符号是键盘左上角‘1’左边那个键。而3'd0中的符号是引号那个键。这在看书的时候,不细心发现,还不容易察觉。重点是作者也没强调。
  2. 软件问题。话了挺长时间弄软件(指的是Modelsim),加上本身对自己写的代码不是特别自信,所以到了后来才发现软件有问题。按照网络上各种方法医治,都无果。没有办法了,自豪使用免费版本的Modelsim(不过,学习的话真的够用了)。
  3. Verilog的相关语法:

    A. 关于阻塞赋值与非阻塞赋值的用法区别。

    B. assign语句赋值号左边只能是wire类型(只在wire与reg型之中做讨论)。而always快语句中,被赋值的只能是reg类型。

  4.在Quartus II中进行中文注释时,往往不能直接输入。最好的方法是先在记事本里将注释写好,然后copy到Quartus II里去。

  5.对数字的写法不要忘记是<位数>’<进制><数字>。

posted @ 2013-02-13 22:20  灰色的鱼  阅读(14839)  评论(0编辑  收藏  举报