兆易创新2022数字芯片笔试题
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 20module 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;endtask cr; integer i; for(i = 0;i <5 ; i = i+1)begin @(posedge clk); a = i[0]; endendtasktask 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; endendtaskalways #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;//lutalways @(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