verilog基础设计6-台积电数字ic笔试verilog编程题

收到联发科笔试邀请,临时抱个佛脚,手动狗头

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、仿真结果

        感觉笔试的时候,想要完整写出代码,并且不出错,还是挺难的,这次的代码也是反复调整时序,才写出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值