在Verilog中测试有限状态机模块
我在为智能家居系统(舒适模块)编写测试台时遇到了一个问题。 舒适度模块采用有限状态机设计。 我应该如何测试模块的循环。 如果运动传感器为1,模块应不断检查温度传感器和温度传感器。 如果有人知道怎么做,我会非常感激在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
`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@*
initial
部分
最后一句话:FSM首先检查温度并忽略灯光状态。
这通常是两个独立变量,但按照您编写的方式,您的FSM无法处理所有组合。您要求为您解决某个
软件问题,但您甚至没有明确定义它。当运动传感器的值设置为开或关时,您可以监控您的信号,只需使用任何合适的软件技术即可请不要这样做。到底是什么阻止了您?而且,由于格式化,您的代码示例几乎不可读。