⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ahbmst.v

📁 appnote65_quickmips_ahb_interface_design_example AHB接口设计
💻 V
📖 第 1 页 / 共 2 页
字号:
// this is the AHB master modelmodule ahbmst (	hclk,	hresetn,	haddr_o,	htrans_o,	hwrite_o,	hburst_o,	hsize_o,	hwdata_o,	hready_i,	hresp_i,	hrdata_i,	hbusreq_o,	hgrant_i);input hclk;input hresetn;output [31:0] haddr_o;output [1:0] htrans_o;output hwrite_o;output [2:0] hburst_o;output [2:0] hsize_o;output [31:0] hwdata_o;input hready_i;input [1:0] hresp_i;input [31:0] hrdata_i;output hbusreq_o;input hgrant_i;`include "ahb_def.v"reg [31:0] haddr_out;reg [1:0] htrans_out;reg hwrite_out;reg [2:0] hburst_out;reg [2:0] hsize_out;reg [31:0] hwdata_out;reg hbusreq_out;assign #OUT_DLY haddr_o = haddr_out;assign #OUT_DLY htrans_o = htrans_out;assign #OUT_DLY hwrite_o = hwrite_out;assign #OUT_DLY hburst_o = hburst_out;assign #OUT_DLY hsize_o = hsize_out;assign #OUT_DLY hwdata_o = hwdata_out;assign #OUT_DLY hbusreq_o = hbusreq_out;wire #IN_DLY hready_in = hready_i;wire [1:0] #IN_DLY hresp_in = hresp_i;wire [31:0] #IN_DLY hrdata_in = hrdata_i;wire #IN_DLY hgrant_in = hgrant_i;// this is the data buffer// it is 8-bit wide to accomodate 8/16-bit transfersreg [7:0] data_array [AHBMST_BUF_DEPTH-1:0];// this is the wait states bufferreg [MAXWS-1:0] wait_states [AHBMST_BUF_DEPTH-1:0];reg [31:0] cur_count;reg [2:0] burst_mod;reg [31:0] cur_addr;reg last_dphase;reg error_rcvd;reg retry_rcvd;reg [31:0] old_addr;reg latch_data;reg next_last_dphase;reg store_rdata_reg;reg comp_rdata_reg;// generate pointer into the data array based on size and cur_countwire [31:0] cur_pointer = (hsize_out == BUS_8) ? cur_count :			((hsize_out == BUS_16) ? cur_count<<1 : cur_count<<2);initial begin	haddr_out <= DEFAULT_ADDR;	htrans_out <= IDLE;	hwrite_out <= READ;	hsize_out <= DEFAULT_SIZE;	hburst_out <= SINGLE;	hwdata_out <= DEFAULT_WDATA;	hbusreq_out <= LOW;	cur_addr = 32'h0;	old_addr = 32'h0;	last_dphase = 1'b0;	next_last_dphase = 1'b0;	error_rcvd = 1'b0;	retry_rcvd = 1'b0;	cur_count = 32'h0;	burst_mod = SINGLE;	latch_data = 1'b0;	comp_rdata_reg = 1'b0;	store_rdata_reg = 1'b0;end// ahb_transfer(addr,size,burst,rn_w,count,store_rdata,comp_rdata,pass_failn)// addr is the AHB address// size is the transfer size// burst is the burst type// rn_w is read (low) or write (high)// count is the number of beats (data phases), not the # of bytes or words// store_rdata is whether to store data read in data_array// comp_rdata is whether to compare read data with data_array and report error when data compare fails// normally if you want to store data then no compare, if you want to compare then no store,// 	but you can also want no store and no compare (just to test the flow)// pass_failn is the return value of whether data compare fails// data is read from data_array during write and stored in data_array during read// wait states are stored in wait_states arraytask ahb_transfer;input [31:0] addr;input [2:0] size;input [2:0] burst;input rn_w;input [AHBMST_BUF_SIZE-1:0] count;input store_rdata;input comp_rdata;output pass_failn;reg result_thistime;begin	// remember some of the attributes	store_rdata_reg <= store_rdata;	comp_rdata_reg <= comp_rdata;	// assume data comparison passes until it fails	pass_failn = 1'b1;	burst_mod = burst;	// make sure HRESETn is high	if (~hresetn) begin		$display("Warning: AHB transfer requested at %t when hresetn is active, delayed", $time);		@(posedge hresetn);		repeat (10) @(posedge hclk);	end	// sanity checks	// size must be 8/16/32-bit	if ((size != BUS_8) && (size != BUS_16) && (size != BUS_32)) begin		$display("Time = %t", $time);		$display("Error: Only 8/16/32-bit transfer sizes are allowed.");		repeat (10) @(posedge hclk);		$finish;	end	// check if address is aligned with the transfer size	if ((size == BUS_16) && (addr[0] != 1'b0) ||	    (size == BUS_32) && (addr[1:0] != 2'b00)) begin		$display("Time = %t", $time);		$display("Error: Address must be aligned with the transfer size.");		$display("\tFor 16-bit transfers, lowest bit of address must be 1'b0.");		$display("\tFor 32-bit transfers, lowest two bits of address must be 2'b00.");		repeat (10) @(posedge hclk);		$finish;	end	// count cannot be 0	if (count == 0) begin		$display("Time = %t", $time);		$display("Error: Transfer count must not be 0.");		repeat (10) @(posedge hclk);		$finish;	end	// check if count matches the burst type	if ((burst == SINGLE) && (count != 1)) begin		$display("Time = %t", $time);		$display("Warning: SINGLE transfer must have a count of 1.");		$display("\tChange burst type to INCR");		burst_mod = INCR;	end	if (((burst == INCR4) || (burst == WRAP4)) && (count != 4)) begin		$display("Time = %t", $time);		$display("Warning: INCR4/WRAP4 transfer must have a count of 4.");		$display("\tChange burst type to INCR");		burst_mod = INCR;	end	if (((burst == INCR8) || (burst == WRAP8)) && (count != 8)) begin		$display("Time = %t", $time);		$display("Warning: INCR8/WRAP8 transfer must have a count of 8.");		$display("\tChange burst type to INCR");		burst_mod = INCR;	end	if (((burst == INCR16) || (burst == WRAP16)) && (count != 16)) begin		$display("Time = %t", $time);		$display("Warning: INCR16/WRAP16 transfer must have a count of 16.");		$display("\tChange burst type to INCR");		burst_mod = INCR;	end	// if INCR4/8/16, must not cross 1KB boundary	// WRAP8/16/32 transfers won't cross 1KB boundary	if (burst_mod == INCR4) begin		if (size == BUS_8) begin			if ((addr[9:2] == 8'hFF) && (addr[1:0] != 2'h0)) begin				$display("Time = %t", $time);				$display("Warning: 8-bit INCR4 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end else if (size == BUS_16) begin			if ((addr[9:3] == 7'h7F) && (addr[2:0] != 3'h0)) begin				$display("Time = %t", $time);				$display("Warning: 16-bit INCR4 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end else begin	// size is BUS_32			if ((addr[9:4] == 6'h3F) && (addr[3:0] != 4'h0)) begin				$display("Time = %t", $time);				$display("Warning: 32-bit INCR4 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end	end else if (burst_mod == INCR8) begin		if (size == BUS_8) begin			if ((addr[9:3] == 8'h7F) && (addr[2:0] != 3'h0)) begin				$display("Time = %t", $time);				$display("Warning: 8-bit INCR8 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end else if (size == BUS_16) begin			if ((addr[9:4] == 6'h3F) && (addr[3:0] != 4'h0)) begin				$display("Time = %t", $time);				$display("Warning: 16-bit INCR8 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end else begin	// size is BUS_32			if ((addr[9:5] == 5'h1F) && (addr[4:0] != 5'h0)) begin				$display("Time = %t", $time);				$display("Warning: 32-bit INCR8 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end	end else if (burst_mod == INCR16) begin		if (size == BUS_8) begin			if ((addr[9:4] == 6'h3F) && (addr[3:0] != 4'h0)) begin				$display("Time = %t", $time);				$display("Warning: 8-bit INCR16 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end else if (size == BUS_16) begin			if ((addr[9:5] == 5'h1F) && (addr[4:0] != 5'h0)) begin				$display("Time = %t", $time);				$display("Warning: 16-bit INCR16 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end else begin	// size is BUS_32			if ((addr[9:6] == 4'hF) && (addr[5:0] != 6'h0)) begin				$display("Time = %t", $time);				$display("Warning: 32-bit INCR16 transfer from address %h will cross 1KB boundary.", addr);				$display("\tChange burst type to INCR");				burst_mod = INCR;			end		end	end	// current and old address register	cur_addr = addr;	old_addr = cur_addr;	// reset counter to count data beats transferred	cur_count = 32'h0;	// reset retry/error flags	retry_rcvd = 1'b0;	error_rcvd = 1'b0;	// reset last data phase flags	last_dphase = 1'b0;	next_last_dphase = 1'b0;	// outside loop over the entire data transfers until all data transferred	// each round is an AHB transaction	// either all data transferred or error received makes it quit	while ((cur_count != count) && ~error_rcvd) begin		last_dphase = 1'b0;		next_last_dphase = 1'b0;		// start requesting bus and driving out all signals		hbusreq_out <= HIGH;		haddr_out <= cur_addr;		hwrite_out <= rn_w;		hsize_out <= size;		// the assignment of hburst_out needs more scrutiny		// once a transfer is force to split at the 1Kbyte boundary or		//	is split/retried by the slave, the subsequent hburst_out

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -