天天看點

verilog基礎設計6-台積電數字ic筆試verilog程式設計題

收到聯發科筆試邀請,臨時抱個佛腳,手動狗頭

1、verilog程式設計題目

請用Verilog寫出以下邏輯。

在data_in的資料中找到特殊字元32’hA1b9_0000,特殊字元前的資料全部丢掉,特殊字元後的資料全部收下來,并且儲存在sync_fifo中,當sync_fifo為非空的時候,将資料讀出放到data_out上,并用data_out_vld訓示資料的有效性。

verilog基礎設計6-台積電數字ic筆試verilog程式設計題

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

verilog基礎設計6-台積電數字ic筆試verilog程式設計題

        感覺筆試的時候,想要完整寫出代碼,并且不出錯,還是挺難的,這次的代碼也是反複調整時序,才寫出來。

繼續閱讀