1、如下图assertion,请问图示波型哪个周期可以判定success?
如图所示,本条断言的意思大体是,EN信号高电平有效,等到A上升沿的时候,其前一个周期(~B)成立,等待0个周期,(B&&~C)成立,等待1个周期,D为1的过程中,(B&&C)语句一直成立,等待1个周期,B成立。
具体语法可点击下面链接:
systemVerilog Assertion (SVA)断言语法_TroubleMaker-CSDN博客
3、信号a是一个变化频率1MHz的无限序列,使用verilog实现,检查并计数序列中1110110的个数。
可以用状态机来实现,但是使用移位寄存器更加简便,具体代码如下:
module seq(
input wire clk,
input wire rstn,
input wire a,
output wire [15:0] number
);
parameter N = 7'b1110110;
reg [15:0]cnt;
reg[6:0] shift_data;
always @(posedge clk or negedge rstn)
if(!rstn)
shift_data<=1'd0;
else
shift_data<={shift_data[5:0],a};
always @(posedge clk or negedge rstn)
if(!rstn)
cnt<=1'd0;
else if(N == shift_data)
cnt<=cnt+1'd1;
assign number = cnt;
endmodule
tb文件:
`timescale 1ns/1ns
`define clk_period 20
module seq_tb;
reg clk;
reg rstn;
reg a;
wire [15:0] number;
initial begin
clk=1'd0;
rstn=1'd0;
a=1'd0;
#20;
rstn=1'd1;
cr;
tr;
#1000;
$stop;
end
task cr;
integer i;
for(i = 0;i <5 ; i = i+1)begin
@(posedge clk);
a = i[0];
end
endtask
task tr;
integer i;
for(i = 0;i <5 ; i = i+1)begin
@(posedge clk);
a = 1'b1;
@(posedge clk);
a = 1'b1;
@(posedge clk);
a = 1'b1;
@(posedge clk);
a = 1'b1;
@(posedge clk);
a = 1'b0;
@(posedge clk);
a = 1'b1;
@(posedge clk);
a = 1'b1;
@(posedge clk);
a = 1'b0;
end
endtask
always #10 clk = ~clk;
seq seq(
.clk ( clk ),
.rstn ( rstn ),
.a ( a ),
.number ( number )
);
endmodule
4、用verilog实现按键消抖电路,输入时钟频率为50MHz,按键信号a低于设定宽度(由cnt_cfg配置:00b表示5ms,01b表示10ms,10b表示15ms,11b表示20ms)时,表示该信号是抖动。
思路:
我们可以这样来实现,当检测到边沿的时候,计数器清零,没有边沿的时候,计数器加1,输入信号持续到cnt_cfg的时候,则认为输入有效
module fit(
input wire clk,//50MHz
input wire rstn,
input wire a,
input wire [1:0] cnt_cfg,
output wire o
);
reg [19:0] N;
reg [19:0] cnt;
reg a_r1,a_r2,a_r3,a_r4;
wire pose_flag,nege_flag;
reg cout;
//lut
always @(posedge clk or negedge rstn)
if(!rstn)
N<=1d'0;
else begin
case(cnt_cfg)
2'b00:N<=19'd249999;
2'b01:N<=19'd499999;
2'b10:N<=19'd749999;
2'b11:N<=19'd999999;
endcase
end
//两级D触发器同步
always @(posedge clk or negedge rstn)
if(!rstn)
{a_r1,a_r2}<=2'd0;
else
{a_r1,a_r2}<={a,a_r1};
//边沿检测
always @(posedge clk or negedge rstn)
if(!rstn)
{a_r3,a_r4}<=2'd0;
else
{a_r3,a_r4}<={a_r2,a_r3};
assign pose_flag = a_r3 && (~a_r4);
assign nege_flag = (~a_r3) && a_r4;
//计数器
always @(posedge clk or negedge rstn)
if(!rstn)
cnt<=1'd0;
else if(pose_flag | nege_flag)
cnt<=1'd0;
else if(cnt == N)
cnt<=1'd0;
else
cnt<=cnt+1'd1;
//输出
always @(posedge clk or negedge rstn)
if(!rstn)
cout<=1'd0;
else if(cnt == N)
cout<=1'd1;
else
cout<=1'd0;
assign o = cout;
endmodule