记录第一次练习使用SystemVerilog的logic声明

发布时间 2023-06-03 08:26:55作者: 颜秋哥

        在学习状态机的编码方式,按照我个人的理解,将电路划分为输入方程,状态方程,输出方程。时序电路的设计,大多都是遵循这三个方程来进行。

        在输出方程里,有两种描述方法:

    // 输出方程:方案一
    assign sm_out = ( current_state == state_C );


    // 输出方程:方案二
    always @ *
    begin
        case ( current_state )
            state_C : sm_out = 1;
            default:  sm_out = 0;
        endcase
    end

         如果使用verilog编码,那么方案一的sm_out,需要定义为wire;方案二的sm_out需要定义为reg。不然在Quartus Prime里编译报错。其实我只是想看看两种方法生成的状态机是否真的一样,就是把书上的代码验证一下。然后就想起来了logic的声明,想到了就试试。最终测试的代码如下:

 1 // 摩尔状态机
 2 module moore_state_machine
 3 (
 4     input logic clk,
 5     input logic reset_n,
 6     
 7     input  logic sm_input,
 8     output logic sm_out 
 9 );
10 
11     reg [1:0] current_state;
12     reg [1:0] next_state;
13     
14     parameter state_A = 2'b00, state_B = 2'b01, state_C = 2'b10;
15      
16      // 输入方程
17     always @ (posedge clk, negedge reset_n)
18     begin
19         if(reset_n == 0)
20             current_state <= state_A;
21         else
22             current_state <= next_state;
23     end 
24     
25     // 状态方程
26     always @ (sm_input, current_state)
27     begin 
28         case (current_state)
29             state_A:
30             begin
31                 if(sm_input == 0) next_state = state_A;
32                 else              next_state = state_B;
33             end
34             
35             state_B:  
36             begin
37                 if(sm_input == 0) next_state = state_B;
38                 else              next_state = state_C;
39             end 
40                 
41             state_C:  
42             begin
43                 if(sm_input == 0) next_state = state_C;
44                 else              next_state = state_A;
45             end 
46                     
47             default:              next_state = state_A;
48         endcase
49     end 
50     
51 
52     // 输出方程
53     //assign sm_out = ( current_state == state_C );
54     always @ *
55     begin
56         case ( current_state )
57             state_C : sm_out = 1;
58             default:  sm_out = 0;
59         endcase
60     end
61 endmodule

         在logic声明下,输出方程的两种方案可以随意切换了。编程语言在不断的进步,很多改进都是为了更方便使用,而这种易用性,常常也是提升编程效率的关键。

         最后,展示一下状态机的状态转换图:

         数字电路,学起来真的比模拟电路快。

        仿真的代码如下:

 1 // Verilog Test Bench template for design : moore_state_machine
 2 // Simulation tool : Questa Intel FPGA (Verilog)
 3 
 4 `timescale 1 ns/ 10 ps
 5 module moore_state_machine_vlg_tst();
 6     reg clk;
 7     reg reset_n;
 8     reg sm_input;
 9     // wires                                               
10     wire sm_out;
11                            
12     moore_state_machine DUT ( 
13         .clk(clk),
14         .reset_n(reset_n),
15         .sm_input(sm_input),
16         .sm_out(sm_out)
17     );
18     
19     initial                                                
20     begin                                                                          
21         clk = 0;
22         reset_n = 0;
23         sm_input = 0;                                           
24         $display("Running testbench");                       
25     end    
26     
27     always                                                                
28     begin                                                  
29         #5 clk = ~clk;                                            
30     end      
31 
32     initial
33     begin
34         #5   reset_n  = 1;
35         #10  sm_input = 1;
36         #100 sm_input = 0;
37         #100 sm_input = 1;
38         #100 sm_input = 0;
39         #100 $stop;
40     end 
41 endmodule

 

        仿真的输出波形如下:

         在Quartus中的RTL Viewer如下,感觉很简洁,根本看不出来啥内容:

         Questa里看Schematic,如下图所示,稍微清晰了一点: