:::info 【知识点】
- 异步复位信号的写法;
- 有限同步状态机怎么写;
- 移位乘法和连接运算符。
:::
看波形:
- 先看rst信号,rst=0的时候,输出为0,也就是说是低电平有效复位信号;
- 当d输入为6的时候,分别输出了6,18,42,48。紧接着输出的是129,而不是128,说明不能根据d信号的变化就对out信号产生影响。
- 通过第二点发现需要一个信号来实现对d信号的寄存,当d发生变化以后,寄存d信号四个周期不发生变化。因此out信号都是根据寄存的信号产生变化,而不是根据实时变化的d信号发生变化。
`timescale 1ns/1ns
module multi_sel(
input [7:0]d,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
//************code**************//
reg [1:0] count;
always @(posedge clk or negedge rst) begin
if(!rst) begin
count <= 2'b00;
end
else begin
count <= count + 2'b01;
end
end
reg [7:0] d_reg;
always @(posedge clk or negedge rst) begin
if(!rst) begin
out <= 11'b0;
input_grant <= 1'b0;
d_reg <= 8'b0;
end
else begin
case(count)
2'b00 : begin
input_grant <= 1'b1;
d_reg <= d;
out <= d;
end
2'b01 : begin
input_grant <= 1'b0;
out <= d_reg + {d_reg, 1'b0};
end
2'b10 : begin
input_grant <= 1'b0;
out <= d_reg + {d_reg, 2'b0} + {d_reg, 1'b0};
end
2'b11 : begin
input_grant <= 1'b0;
out <= {d_reg, 3'b0};
end
default : begin
input_grant <= 1'b0;
d_reg <= d;
out <= d_reg;
end
endcase
end
end
//************code**************//
endmodule
当使用非阻塞赋值语句的时候,输出相对于输入延后一个clk周期; 需要一个寄存器类型的变量对寄存器进行寄存,且根据该寄存器类型的变量来编写状态机:
- 将复位信号及状态写在时序逻辑电路中;
- 根据电平触发来描述若干状态机的状态。
具体参考:3.2 行为级建模【重要】中关于过程赋值语句的部分。
【调试bug】
在input_grant拉高的周期中,out输出的结果为并不是d,说明输出的是rst_n以后的d的值,原因是在always块中使用了非阻塞赋值语句,赋值的就是上一个周期d_reg的值。而rst_n周期内d_reg的值为0。