在Verilog中测试有限状态机模块

在Verilog中测试有限状态机模块,verilog,fpga,test-bench,Verilog,Fpga,Test Bench,我在为智能家居系统(舒适模块)编写测试台时遇到了一个问题。 舒适度模块采用有限状态机设计。 我应该如何测试模块的循环。 如果运动传感器为1,模块应不断检查温度传感器和温度传感器。 如果有人知道怎么做,我会非常感激 `define start 4'd0 `define temp_heat 4'd1 `define temp_cool 4'd2 `define light_bright 4'd3 `define light_dim 4'd4 module comfort (clk

我在为智能家居系统(舒适模块)编写测试台时遇到了一个问题。 舒适度模块采用有限状态机设计。 我应该如何测试模块的循环。 如果运动传感器为1,模块应不断检查温度传感器和温度传感器。 如果有人知道怎么做,我会非常感激

 `define start 4'd0 
 `define temp_heat 4'd1 
 `define temp_cool 4'd2 
 `define light_bright 4'd3 
 `define light_dim 4'd4 
module comfort (clk,reset,motion_sen,temp_sen,lume_sen,light,heater,cooler,light_high,light_low); 

input  clk,reset,motion_sen;
input [7:0] temp_sen,lume_sen; 
output reg heater,cooler,light_high,light_low,light;

reg [3:0] current_state;
reg [3:0] next_state;
wire clk; 
initial begin 
      current_state=`start;
  next_state= `start;
     heater='b0;
     cooler='b0;
     light_high='b0; 
     light_low='b0; 
     light='b0; 
end 
  always @(posedge clk) 
 current_state=next_state; 
 always @(current_state) 
 begin 
     case(current_state)
     `start: 
     begin 
         heater='b0; 
         cooler='b0; 
         light_high='b0; 
         light_low='b0;light='b0; 
     end 
 `temp_heat: 
     begin 
         if(motion_sen==1)                   
             begin 
                 heater ='b1; 
                 cooler='b0;
                 light='b1;
                 end                    
         else                     
         heater ='b0;
         end 
 `temp_cool:
    begin 
 if(motion_sen==1)                    
      begin 
  cooler ='b1;
      heater ='b0;
  light='b1;
  end                     
 else 
 cooler ='b0;
 end 
 `light_bright:
 begin 
 if(motion_sen==1)                  
 begin 
 light_high ='b1;
 light_low='b0;
 light='b1;
 end           
 else 
     light_high ='b0;
 end       
  `light_dim:
  begin 
  if(motion_sen==1)                
   begin   
 light_low ='b1;
 light_high='b0;
 end             
 else  
 light_low ='b0;
 end 
 endcase 
 end 

always  @(current_state,temp_sen,lume_sen,reset)
 begin 
     if(reset=='b1) 
         next_state=`start;
     else  
         case(current_state)
             `start: 
                 begin 
                     if(temp_sen> 'b00011110)
                         next_state=`temp_cool; 
                     else if(temp_sen< 'b00001111) 
                         next_state=`temp_heat; 
                     else if(lume_sen > 'b00001111) 
                         next_state=`light_dim;
                     else if (lume_sen < 'b00001010)
                         next_state=`light_bright; 
                 end  
             `temp_cool: 
                 begin  
                     if(temp_sen< 'b00001111)
                         next_state=`temp_heat;
                     else if (lume_sen > 'b00001111)
                         next_state=`light_dim;
                     else if(lume_sen < 'b00001010)
                         next_state=`light_bright;
                 end 
             `temp_heat: 
                 begin   
                     if(temp_sen> 'b00011110) 
                         next_state=`temp_cool;
                     else if (lume_sen > 'b00001111)
                         next_state= `light_dim;
                     else if(lume_sen < 'b00001010)
                     next_state= `light_bright; 
                 end  
             `light_dim: 
                 begin 
                     if(lume_sen < 'b00001111)
                         next_state=`light_bright;
                 end 
             `light_bright:
                 begin
                     next_state=`start;
                 end 
             endcase  
         end 
     endmodule
`define start 4'd0
`定义4’d1的温度
`定义温度4'd2
`定义灯光亮度4'd3
`定义灯光尺寸4'd4
模块舒适性(时钟、复位、运动传感器、温度传感器、亮度传感器、灯、加热器、冷却器、灯高、灯低);
输入时钟、复位、运动传感器;
输入[7:0]温度传感器、温度传感器;
输出reg加热器、冷却器、灯高、灯低、灯;
reg[3:0]当前_状态;
reg[3:0]下一个州;
电线电缆;
初始开始
当前_状态=`开始;
next_state=`开始;
加热器=b0;
冷却器=b0;
轻_高='b0;
光照低='b0;
光=b0;
结束
始终@(posedge clk)
当前_状态=下一个_状态;
始终@(当前状态)
开始
案例(当前状态)
`开始:
开始
加热器=b0;
冷却器=b0;
轻_高='b0;
光照低='b0;光=b0;
结束
`温度/热量:
开始
如果(运动=1)
开始
加热器b1;
冷却器=b0;
光b1;
结束
其他的
加热器=b0;
结束
`温度冷却:
开始
如果(运动=1)
开始
冷却器b1;
加热器=b0;
光b1;
结束
其他的
冷却器=b0;
结束
`灯光明亮:
开始
如果(运动=1)
开始
轻(u高)b1 ;;
光照低='b0;
光b1;
结束
其他的
轻_高='b0;
结束
`灯光昏暗:
开始
如果(运动=1)
开始
轻(低)b1 ;;
轻_高='b0;
结束
其他的
光照低='b0;
结束
尾声
结束
始终@(当前状态、温度传感器、温度传感器、复位)
开始
如果(重置=='b1)
next_state=`开始;
其他的
案例(当前状态)
`开始:
开始
如果(温度传感器>'b00011110)
next_state=`temp_cool;
否则如果(温度传感器<'b00001111)
下一个状态=`temp\u heat;
否则,如果(lume_sen>'b00001111)
next_state=`light_dim;
否则如果(卢梅森<'b00001010)
next_state=`light_bright;
结束
`温度冷却:
开始
如果(温度传感器<'b00001111)
下一个状态=`temp\u heat;
否则,如果(lume_sen>'b00001111)
next_state=`light_dim;
否则如果(卢梅森<'b00001010)
next_state=`light_bright;
结束
`温度/热量:
开始
如果(温度传感器>'b00011110)
next_state=`temp_cool;
否则,如果(lume_sen>'b00001111)
next_state=`light_dim;
否则如果(卢梅森<'b00001010)
next_state=`light_bright;
结束
`灯光昏暗:
开始
如果(卢梅森<'b00001111)
next_state=`light_bright;
结束
`灯光明亮:
开始
next_state=`开始;
结束
尾声
结束
端模

测试,就像好的编码是一门艺术一样。那我就不能教你/告诉你其他人了

“熟能生巧”

一个程序是提供输入,使FSM处于状态X,然后测试是否是这种情况。其中最困难的部分是预测,您必须在不重复FSM代码的情况下编写FSM的等效代码。(这就是为什么理想情况下你会有其他人,例如使用UVM测试你的代码)

试着得到一个代码覆盖率高的模拟器,它会告诉你是否测试过每一个(角落)案例


说到这里,我认为您应该首先重新访问当前的代码,因为它的风格是相当非正统的。以下是我对当前代码的一些问题:

  • 改进格式:修复缩进并在“始终”部分之间添加空行
  • 使用ANSI样式的端口定义:
    (输入时钟,…输出调节加热器…)
  • 尽量少用宏。对常量使用localparam
  • 常量使用所有大写字母
  • 添加指示器,例如所有状态常数以ST开头_
  • 不要将二进制数用作值。8'd30比'b00011110'更能说明问题
  • 您的代码已满闩锁。使用默认值或为每个状态中的每个变量指定一个值
  • 不要使用
    always@(当前状态、温度传感器…
    而使用
    always\u梳
    always@*
在RTL代码中使用“initial”有很大的争议,一些人说可以,其他人说使用reset(我在后一阵营)。你有一个reset信号,所以我建议你使用它并删除
initial
部分

最后一句话:
FSM首先检查温度并忽略灯光状态。
这通常是两个独立变量,但按照您编写的方式,您的FSM无法处理所有组合。

您要求为您解决某个
软件问题,但您甚至没有明确定义它。当运动传感器的值设置为开或关时,您可以监控您的信号,只需使用任何合适的软件技术即可请不要这样做。到底是什么阻止了您?而且,由于格式化,您的代码示例几乎不可读。