Verilog 代码题练手(1)
引言
本专栏主要针对往年IC笔试的真题进行编程练习。题解思路不唯一,希望可以交流。我的代码只是能说是按照我对题目的理解进行编写。有出入的地方可以留言交流。
每道题目会给出设计代码、TESTBENCH、仿真结果。
每篇博客 题目数为 1 ,不止是代码,也有思路分析。
本专栏有时间就会继续更新,欢迎订阅关注~
序列检测
(乐鑫某年笔试题目)模块持续每拍并行输入2bit数,请实现对(1011001)的序列检测功能,输入数据的顺序为高位2bit先输入,当检测到该序列时,输出一拍高电平脉冲信号。请用Verilog完整描述该模块。
思路:
这里简单说明我的思路:
此题输入为双比特输入,同时给进两位数,但是待检测的序列长度为7(奇数);所以常规的单比特输入序列检测不再适用。下面给出一种移位寄存器的解决方法:
1、复位信号拉低,模块复位,寄存器、计数器清零;
2、复位撤离,输入有效信号拉高,开始左移寄存,并计数;
3、计数器计数到4后,若有效信号不拉低则一直保持4,否则清零;
4、计数器计数到4后,判断移位寄存器内的高7位,或者低7位和目标序列比对,如果匹配则表明检测到目标序列;
下面对 4 中的表述进行解释:
高7位匹配:如蓝色序列形式,即序列匹配的第一个bit在输入信号中的高位;
低7位匹配:如红色序列形式,即序列匹配的第一个bit在输入信号中的低位;
设计文件:
`timescale 1ns / 1ps
// 序列检测:
// 说明:
// -1- 模块持续每拍并行输入2bit数;
// -2- 请实现对(1011001)的序列检测功能,输入数据的顺序为高位2bit先输入;
// -3- 当检测到该序列时,输出一拍高电平脉冲信号。
// By:在路上,正出发
module Sque_Detect(
input I_CLK,
input I_RSTN,
input [1:0] I_SEQUE,
input I_VAL,
output O_DETECT
);
reg [7:0] R_SEQUE_8;
reg [2:0] R_COUNT_4;
always @ (posedge I_CLK)
begin
if(~I_RSTN)
begin
R_SEQUE_8 <= 8'd0;
R_COUNT_4 <= 3'd0;
end
else
begin
if(I_VAL)
begin
R_SEQUE_8 <= {R_SEQUE_8[11:0],I_SEQUE};
if(R_COUNT_4 == 3'd4)
begin
R_COUNT_4 <= 3'd4;
end
else
begin
R_COUNT_4 <= R_COUNT_4 + 1;
end
end
else // 数据输入无效 此时认为不需要进行序列检测
begin // 将寄存器 计数器清零 为下一次检测做准备
R_SEQUE_8 <= 8'd0;
R_COUNT_4 <= 3'd0;
end
end
end
reg R_DETECT;
always @ (posedge I_CLK)
begin
if(~I_RSTN)
begin
R_DETECT <= 0;
end
else
begin
case(R_COUNT_4)
4:
begin
if((R_SEQUE_8[7:1] == 7'b1011001) || (R_SEQUE_8[6:0] == 7'b1011001))
begin
R_DETECT <= 1'b1;
end
else
begin
R_DETECT <= 1'b0;
end
end
default:
begin
R_DETECT <= 1'b0;
end
endcase
end
end
assign O_DETECT = R_DETECT;
endmodule
TEST_BENCH:
`timescale 1ns / 1ps
// By:在路上,正出发
module TB_SEQUE_DETECT();
reg I_CLK;
reg I_RSTN;
reg [1:0] I_SEQUE;
reg I_VAL;
wire O_DETECT;
// 时钟
initial I_CLK = 1'b0;
always # 10 I_CLK = ~I_CLK;
initial
begin
I_RSTN = 0;
I_VAL = 0;
I_SEQUE = 2'b00;
#100;
I_RSTN = 1'b1;
#80;
repeat(100)
begin
@(posedge I_CLK);
I_VAL = 1'b1;
I_SEQUE = 2'b11;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b10;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b11;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b00;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b11;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b01;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b10;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b01;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b10;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b11;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b00;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b10;
end
#100;
I_VAL = 0;
I_SEQUE = 2'b11;
#(20*1000);
repeat(100)
begin
@(posedge I_CLK);
I_VAL = 1'b1;
I_SEQUE = 2'b11;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b10;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b11;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b00;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b11;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b01;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b10;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b01;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b10;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b11;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b00;
#20;
I_VAL = 1'b1;
I_SEQUE = 2'b10;
end
end
Sque_Detect inst_Sque_Detect
(
.I_CLK (I_CLK),
.I_RSTN (I_RSTN),
.I_SEQUE (I_SEQUE),
.I_VAL (I_VAL),
.O_DETECT (O_DETECT)
);
endmodule
仿真结果:
细节: