收到联发科笔试邀请,临时抱个佛脚,手动狗头
1、verilog编程题目
请用Verilog写出以下逻辑。
在data_in的数据中找到特殊字符32’hA1b9_0000,特殊字符前的数据全部丢掉,特殊字符后的数据全部收下来,并且保存在sync_fifo中,当sync_fifo为非空的时候,将数据读出放到data_out上,并用data_out_vld指示数据的有效性。
2、题目分析
本题的代码实现主要分为两部分
- 第一部分是检测到指定数据,也就是32’hA1b9_0000
- 第二部分就是对检测到的数据,及其之后的数据进行存储,和读出,本题也有提示其实就是自己写一个同步fifo,当检测到数据之后,给出相应的读使能和写使能,写入和读出数据,所以再实现整个代码前我特定复习了以下同步fifo的实现
- 接下来我们就写代码
3、verilog实现
module filter_data_store(
input wire clk_ck,
input wire rst_b,
input wire req_in,
output reg req_in_ack,
input wire [31:0] data_in,
output reg data_out_vld,
output reg [31:0] data_out
);
wire data_in_valid;
reg data_in_valid_reg0,data_in_valid_reg1;
reg [31:0] data_in_reg,data_in_reg1;
reg find_out;
reg [31:0] mem [15:0];
wire empty;
wire full;
reg [3:0] rd_addr;
reg [3:0] wr_addr;
wire rd_en;
wire wr_en;
reg [3:0] count;
localparam deepth = 4'd15;
assign empty =(count == 4'd0)? 1'b1: 1'b0 ;
assign full = (count == 4'd15) ? 1'b1:1'b0;
assign data_in_valid = (req_in & req_in_ack);
assign rd_en = (~empty);
always @(posedge clk_ck or negedge rst_b) begin
{data_in_valid_reg1,data_in_valid_reg0} ={data_in_valid_reg0,data_in_valid};
end
always @(posedge clk_ck or negedge rst_b)
if(!rst_b)
req_in_ack <= 1'b0;
else if(req_in)
req_in_ack <= 1'b1;
else
req_in_ack <= 1'b0;
always @(posedge clk_ck or negedge rst_b) begin
if (!rst_b)
data_in_reg <= 32'd0;
else if (data_in_valid)
data_in_reg <= data_in;
else begin
data_in_reg <= 32'd0;
end
end
always @(posedge clk_ck)
if(!rst_b)
data_in_reg1 <= 32'd0;
else
data_in_reg1 <= data_in_reg;
always @(posedge clk_ck or negedge rst_b) begin
if (!rst_b)
find_out <= 1'b0;
else if (data_in_valid && data_in_reg == 32'hA1B9_0000 )
find_out <= 1'b1;
else
find_out <= find_out;
end
assign wr_en = (find_out && ~full && data_in_valid_reg1);
always @(posedge clk_ck or negedge rst_b)
if(!rst_b)
wr_addr <= 4'd0;
else if (wr_en) begin
mem[wr_addr] = data_in_reg1;
wr_addr <= wr_addr + 1'b1;
end
else begin
mem[wr_addr] <= mem[wr_addr];
wr_addr <= wr_addr;
end
always @(posedge clk_ck or negedge rst_b)
if(!rst_b) begin
rd_addr <= 4'd0;
data_out <= 32'd0;
data_out_vld <= 1'b0;
end
else if(rd_en) begin
data_out <= mem[rd_addr];
rd_addr <= rd_addr + 1'b1;
data_out_vld <= 1'b1;
end
else begin
rd_addr <= rd_addr;
data_out <= data_out;
data_out_vld<= 1'b0;
end
//count 的控制
always @(posedge clk_ck or negedge rst_b)
if(!rst_b)
count <= 4'd0;
else if(wr_en && ~rd_en)
count <= count + 1'b1;
else if(rd_en && ~wr_en)
count <= count - 1'b1;
else
count <= count;
endmodule
4、模块的仿真代码
`timescale 1ns/1ps
module tb_mtk();
reg clk;
reg rst_n;
reg req_in;
wire req_in_ack;
reg [31:0] data_in;
wire data_out_vld;
wire [31:0] data_out;
initial begin
clk = 0;
rst_n =0;
//req_in_ack =0;
req_in =0;
data_in =0;
#100;
rst_n = 1;
#1000;
req_in = 1'b1;
data_in = 32'h53;
#20;
data_in = 32'h01;
#20;
data_in = 32'h11;
#20;
data_in = 32'hA1B9_0000;
#20;
data_in = 32'h05;
#20;
data_in = 32'h01;
#20;
data_in = 32'h02;
#20;
data_in = 32'h05;
#20;
data_in = 32'h01;
#20;
data_in = 32'h02;
#20;
data_in = 32'h05;
#20;
data_in = 32'h01;
#20;
data_in = 32'h02;
#20;
data_in = 32'h02;
#20;
data_in = 32'h05;
#20;
data_in = 32'h01;
#20;
data_in = 32'h02;
#20;
data_in = 32'h05;
#20;
data_in = 32'h01;
#20;
data_in = 32'h02;
#20;
req_in = 0;
end
always #10 clk = ~clk;
filter_data_store filter_data_store_inst(
.clk_ck(clk),
.rst_b(rst_n),
.req_in(req_in),
.req_in_ack(req_in_ack),
.data_in(data_in),
.data_out_vld(data_out_vld),
.data_out(data_out)
);
endmodule
5、仿真结果
感觉笔试的时候,想要完整写出代码,并且不出错,还是挺难的,这次的代码也是反复调整时序,才写出来。