1.VL25 输入序列连续的序列检测
1.题目:
请编写一个序列检测模块,检测输入信号a是否满足01110001序列,当信号满足该序列,给出指示信号match。
模块的接口信号图如下:
2.解题思路
2. 1 首先 暴力的手段, 使用 {} 组合逻辑 左移寄存器 最右边添加 a的值。 对比 寄存器的值输出 match 的值。 ( 下下个状态 使用 always 的 非堵塞赋值可以)
2.2 使用 三段的 状态机
3.解题代码
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg[7:0] gg;
always@(posedge clk or negedge rst_n)
if(~rst_n)
match <=0;
else if(gg == 8'b0111_0001)
match <= 1;
else
match <=0;
always@(posedge clk or negedge rst_n)
if(~rst_n)
begin
gg <= 8'b0;
end
else
begin
gg <= {gg[6:0],a};
end
endmodule
2.VL26 含有无关项的序列检测
1.题目:
请编写一个序列检测模块,检测输入信号a是否满足011XXX110序列(长度为9位数据,前三位是011,后三位是110,中间三位不做要求),当信号满足该序列,给出指示信号match。
2.解题思路
2. 1 首先 暴力的手段, 使用 {} 组合逻辑 左移寄存器 最右边添加 a的值。 对比 寄存器的值输出 match 的值。 ( 下下个状态 使用 always 的 非堵塞赋值可以)
2.2 使用 9 段的 状态机
3.解题代码
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg[8:0] gg;
always@(posedge clk or negedge rst_n)
if(~rst_n)
match <=0;
else if(gg[8:6] == 3'b011 & gg[2:0] == 3'b110)
match <= 1;
else
match <=0;
always@(posedge clk or negedge rst_n)
if(~rst_n)
begin
gg <= 9'b0;
end
else
begin
gg <= {gg[7:0],a};
end
endmodule
3.VL27 不重叠序列检测
1.题目:
请编写一个序列检测模块,检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match。
模块的接口信号图如下:
2.解题思路
1.在最后一个周期前判断 match 的输出值。 方法其他一样。
3.解题代码
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
reg [5:0] seq;
reg [3:0] counter;
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
seq <= 6'b0;
match <= 1'b0;
not_match <= 1'b0;
end
else
seq <= { seq[4:0], data };
end
always@(posedge clk) begin
if(!rst_n) begin
counter <= 0;
end
else if(counter=='d5)
counter <= 0;
else begin
counter <= counter + 1;
end
end
always@(posedge clk)begin
if( {seq[4:0],data}==6'b011100 && counter=='d5 ) begin
match <= 1;
end
else begin
match <= 0;
end
end
always@(posedge clk)begin
if( {seq[4:0],data}!=6'b011100 && counter=='d5 ) begin
not_match <= 1;
end
else begin
not_match <= 0;
end
end
endmodule
4.VL28 输入序列连续的序列检测
1.题目:
请编写一个序列检测模块,输入信号端口为data,表示数据有效的指示信号端口为data_valid。当data_valid信号为高时,表示此刻的输入信号data有效,参与序列检测;当data_valid为低时,data无效,抛弃该时刻的输入。当输入序列的有效信号满足0110时,拉高序列匹配信号match。
模块的接口信号图如下:
2.解题思路
2.1 1.在最后一个周期前判断 match 的输出值。 方法其他一样。
3.解题代码
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
input data_valid,
output reg match
);
reg[3:0] gg; //数据储存寄存器
always@(posedge clk or negedge rst_n)
if(~rst_n)
begin
gg <= 4'b0;
end
else
begin
if(data_valid == 1'b1)
gg <= {gg[2:0],data};
else
gg <= 4'b0000;
end
always@(posedge clk or negedge rst_n)
if(~rst_n)
begin
match <=0;
end
else
begin
if(data_valid && gg[2 : 0] == 3'b011 && !data )// 假如是 gg == 4'b0110 他是下一个时刻 match =1 ,
begin
match <=1;
end
else
begin
match <=0;
end
end
endmodule
5.做这个部分总的感受 和 学到新的知识
5.1 周期延时问题。
//输出,使用时序将match延后一个周期,不延后可以用assign match = (curr_state == S8);
//注意,使用assign需将match类型改为wire
/*always@(posedge clk or negedge rst_n) begin /延时
if(rst_n == 0)
match <= 0;
else
match = (curr_state == S4);
end*/
assign match = (curr_state == S4);//不延时
5.2堵塞 赋值 和非堵塞赋值
5.2.1一个链接:
Verilog语法之六:阻塞赋值与非阻塞赋值 - 知乎 (zhihu.com)
5.2.2我的理解: 堵塞赋值 等于 立即赋值。
非堵塞赋值 等于 模块结束后 赋值。
所以状态机 里面的顺序可以理解了。
always 并行的。 但是 下一个状态 nextstatu 是 阻塞赋值。 立即赋值
statu 是 非堵塞赋值。 是在 neststatu 后面赋值。
5.2.3 关于输出的周期问题
首先使用 always 的非堵塞赋值 会延时1 个周期。
使用 assign 赋值 输出会在下一个周期执行。