並口parall_interf

模塊代碼

module parall_interf(
	input 	wire 			sclk,
	input 	wire 			rst_n,
	input 	wire			cs_n,
	input 	wire 			rd_n,
	input	wire			wr_n,
	inout   tri 	[15:0] 	data,
	input 	wire 	[7:0] 	addr
);

reg 	[15:0]		data_0,data_1,data_2,data_3,
					data_4,data_5,data_6,data_7;

reg 	[2:0]		cs_n_r,rd_n_r,wr_n_r;
reg 	[47:0]		data_r;
reg 	[23:0]		addr_r;
reg 	[15:0]      rdata;


assign 	data = (cs_n_r[2] == 1'b0 && rd_n_r[2]== 1'b0) ? rdata : 16'hzzzz;


//去降低穩態出現概率把cs_n,rd_n,wr_n 單比特信號打兩拍
always @(posedge sclk or negedge rst_n)
		if(rst_n == 1'b0)
			{cs_n_r,rd_n_r,wr_n_r} <= 9'h1ff;
		else 
			{cs_n_r,rd_n_r,wr_n_r} <= {{cs_n_r[1:0],cs_n},{rd_n_r[1:0],rd_n},{wr_n_r[1:0],wr_n}};
			
always @(posedge sclk or negedge rst_n)
		if(rst_n == 1'b0) begin
			data_r <= 48'd0;
			addr_r <= 24'd0;
		end
		else begin
			data_r <= {data_r[31:0],data};
			addr_r <= {addr_r[15:0],addr};
		end

always @(posedge sclk or negedge rst_n)
		if(rst_n == 1'b0) begin
			data_0 <= 16'd0;
			data_1 <= 16'd0;
			data_2 <= 16'd0;
			data_3 <= 16'd0;
			data_4 <= 16'd0;
			data_5 <= 16'd0;
			data_6 <= 16'd0;
			data_7 <= 16'd0;
		end
		else if(cs_n_r[2] == 1'b0 && rd_n_r[2] == 1'b1 && wr_n_r[2] == 1'b0)begin
			case(addr_r[23:16])
				8'd0:data_0 <= data_r[47:32]; 
				8'd1:data_1 <= data_r[47:32];
				8'd2:data_2 <= data_r[47:32]; 
				8'd3:data_3 <= data_r[47:32];
				8'd4:data_4 <= data_r[47:32];
				8'd5:data_5 <= data_r[47:32];
				8'd6:data_6 <= data_r[47:32]; 
				8'd7:data_7 <= data_r[47:32];
			  default:begin
				  data_0 <= data_0;
				  data_1 <= data_1;
				  data_2 <= data_2;
				  data_3 <= data_3;
				  data_4 <= data_4;
				  data_5 <= data_5;
				  data_6 <= data_6;
				  data_7 <= data_7;
			  end
			endcase
		end

always @(posedge sclk or negedge rst_n) 
		if(rst_n == 1'b0)
			rdata <= 16'hffff;
		else if(cs_n_r[2] ==  1'b0 && rd_n_r[2] == 1'b1 && wr_n_r[2] == 1'b1) begin
			case(addr_r[23:16])
				8'd0:rdata <= data_0; 
				8'd1:rdata <= data_1;
				8'd2:rdata <= data_2; 
				8'd3:rdata <= data_3;
				8'd4:rdata <= data_4;
				8'd5:rdata <= data_5;
				8'd6:rdata <= data_6; 
				8'd7:rdata <= data_7;
				
				default:rdata <= 16'd0;
			endcase
		end
		
endmodule

測試文件

`timescale 1ns/1ns
module parall_interf_tb;

parameter 		SETUP_TIME	= 2;
parameter 		HOLD_TIME  	= 2;
parameter 		DATA_TIME 	= 4;
parameter 		READ_WAIT 	= 5;

reg 			sclk;
reg 			rst_n;
reg 			cs_n;
reg 			rd_n;
reg 			wr_n;
reg 	[15:0]	data;
reg 	[7:0] 	addr;
tri 	[15:0]  w_data;

initial begin
		sclk = 0;
		rst_n = 0;
		#200
		rst_n = 1;
end

always #10 sclk = ~sclk;

initial begin
		cs_n = 1;
		rd_n = 1;
		wr_n = 1;
		data = 0;
		addr = 0;
		
		//@(posedge rst_n);
		#300
		write_data(8);
		#100;
		read_data(8);
end

//測試激勵的三態門
assign	w_data = (wr_n==1'b0)?data:16'hzzzz;

parall_interf parall_interf_inst(
	.sclk		(sclk),//50mhz
	.rst_n		(rst_n),
	.cs_n		(cs_n),
	.rd_n		(rd_n),
	.wr_n		(wr_n),
	.data		(w_data),//1Mhz
	.addr		(addr)
);

//寫數據的任務
task 	write_data(len);
		integer i,len;
		begin
				for(i=0;i<len;i=i+1)
				begin
					cs_n = 0;
					data = i[15:0];
					addr = i[7:0];
					setup_dly();
					wr_n = 0;
					data_dly();
					wr_n = 1;
					hold_dly();
				end
				cs_n = 1;
		end
endtask

//讀數據任務
task 	read_data(len);
		integer i,len;
		begin
				for(i=0;i<len;i=i+1)
				begin
					cs_n = 0;
					addr = i[7:0];
					read_dly();
					rd_n = 0;
					data_dly();
					$display("read data addr is %d = %d ",i,w_data);
					rd_n = 1;
				end
				cs_n = 1;
		end
endtask
//基本的延時任務
task 	setup_dly();
		integer i;
		begin
				for(i=0;i<SETUP_TIME;i=i+1)
				begin
					@(posedge sclk);
				end
		end
endtask
				
task 	hold_dly();
		integer i;
		begin
				for(i=0;i<HOLD_TIME;i=i+1)
				begin
					@(posedge sclk);
				end
		end
endtask
				
task 	data_dly();
		integer i;
		begin
				for(i=0;i<DATA_TIME;i=i+1)
				begin
					@(posedge sclk);
				end
		end
endtask
				
task 	read_dly();
		integer i;
		begin
				for(i=0;i<READ_WAIT;i=i+1)
				begin
					@(posedge sclk);
				end
		end
endtask

endmodule
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章