?? fifo.v
字號:
`timescale 1ns / 1psmodule FIFO(HCLK, HRESETn, HADDR, HTRANS, HWRITE, HSIZE, HWDATA, HSEL, HREADY, HRDATA, HREADYOUT, HRESP); input HCLK; input HRESETn; input [31:0] HADDR; input [1:0] HTRANS; input HWRITE; input [2:0] HSIZE; input [31:0] HWDATA; input HSEL; input HREADY; output [31:0] HRDATA; output HREADYOUT; output [1:0] HRESP;//------------------------------------------------------------------------------// Default memory size and input filename settings//------------------------------------------------------------------------------// parameter MemBits = 10; // Memory size in address bits, 1kB default// parameter FileName = "intram.dat"; // Input filename//------------------------------------------------------------------------------// Constant declarations//------------------------------------------------------------------------------// HTRANS transfer type signal encoding `define TRN_IDLE 2'b00 `define TRN_BUSY 2'b01 `define TRN_NONSEQ 2'b10 `define TRN_SEQ 2'b11// HSIZE transfer type signal encoding `define SZ_BYTE 3'b000 `define SZ_HALF 3'b001 `define SZ_WORD 3'b010 `define SZ_DWORD 3'b011// HRESP transfer response signal encoding `define RSP_OKAY 2'b00 `define RSP_ERROR 2'b01 `define RSP_RETRY 2'b10 `define RSP_SPLIT 2'b11// Number of memory locations `define MEM_ARRAY_MAX ((1 << MemBits - 2) -1) //------------------------------------------------------------------------------// Signal declarations//------------------------------------------------------------------------------// Input/Output Signals wire HCLK; wire HRESETn; wire [31:0] HADDR; wire [1:0] HTRANS; wire HWRITE; wire [2:0] HSIZE; wire [31:0] HWDATA; wire HSEL; wire HREADY; wire HREADYOUT; reg [1:0] HRESP; reg [31:0] HRDATA;// fifo signals reg [3:0] read_ptr,write_ptr;//counter; reg [31:0] ram [31:0]; reg [31:0] Data; // Temporary data store for output// reg [31:0] Datain; // Temporary data store for input // Memory signals// reg [31:0] Mem [0:`MEM_ARRAY_MAX]; // Memory register array// reg [31:0] Data; // Temporary data store// integer MemAddr; // Memory address being accessed integer i; // Loop counter for memory initialisation // Control Signals wire ValidReg; // valid data phase wire ACRegEn; // enable for address and control registers // Signals registered into data phase reg HselReg; // registered HSEL reg [31:0] HaddrReg; // registered HADDR reg [1:0] HtransReg; // registered HTRANS reg HwriteReg; // registered HWRITE reg [2:0] HsizeReg; // registered HSIZE // Ready/Response Signals wire Invalid; // indicates an ERROR response required wire [1:0] HrespNext; // D-input of HRESP register wire HreadyNext; // D-input of HREADYOUT register reg iHREADYOUT; // internal version of HREADYOUT output//------------------------------------------------------------------------------// Initialise FIFO (only once)//------------------------------------------------------------------------------ initial begin ram[0] = 32'h0000_0004; end// initial// begin// for (i = 0; i <= 31; i = i + 1) // ram[i] = 32'h0000_0000; // ValidReg = 1; // end//------------------------------------------------------------------------------// Beginning of main code//------------------------------------------------------------------------------//------------------------------------------------------------------------------// Valid transfer detection//------------------------------------------------------------------------------// The slave must only respond to a valid transfer, so this must be detected. always @(negedge (HRESETn) or posedge (HCLK)) begin if (!HRESETn) HselReg <= 1'b0; else begin if (HREADY) HselReg <= HSEL; end end // Valid AHB transfers only take place when a non-sequential or sequential// transfer is shown on HTRANS - an idle or busy transfer should be ignored. assign ValidReg = (HselReg == 1'b1 && (HtransReg == `TRN_NONSEQ || HtransReg == `TRN_SEQ)) ? 1'b1 : 1'b0;//------------------------------------------------------------------------------// Address and control registers//------------------------------------------------------------------------------// Registers are used to store the address and control signals from the address// phase for use in the data phase of the transfer.// Only enabled when the HREADY input is HIGH and the module is addressed. assign ACRegEn = HSEL & HREADY; always @(negedge (HRESETn) or posedge (HCLK)) begin if (!HRESETn) begin HaddrReg <= 32'h0000_0000; HtransReg <= 2'b00; HwriteReg <= 1'b0; HsizeReg <= 3'b000; read_ptr <= 1'b0; write_ptr <= 1'b0; // counter <= 1'b0; end else begin if (ACRegEn) begin HaddrReg <= HADDR; HtransReg <= HTRANS; HwriteReg <= HWRITE; HsizeReg <= HSIZE; end end end//------------------------------------------------------------------------------// FIFO read and write//------------------------------------------------------------------------------ always @(ValidReg or HaddrReg or HCLK) begin if (ValidReg) // Common to read and write operations// HRDATA =0;// Dataout=ram[read_ptr];// counter=counter-1;// read_ptr=(read_ptr==31)?0:read_ptr+1;// begin// MemAddr = HaddrReg[MemBits-1 : 2]; // Memory address for this transfer// Data = Mem[MemAddr]; // Data from addressed location @(posedge HCLK) // Write-only section performed on the rising clock edge if (HwriteReg && ValidReg ) begin if(HADDR == 32'h400000004) begin Data = HWDATA; ram[write_ptr] = Data; write_ptr=(write_ptr==31)?0:write_ptr+1; end end end //------------------------------------------------------------------------------// Output Drivers//------------------------------------------------------------------------------// Drive output data bus during read operation always @(ValidReg or HwriteReg or Data) begin if (ValidReg && !HwriteReg ) // Valid read transfer begin if(HADDR == 32'h400000004) begin Data=ram[read_ptr];// counter=counter-1; read_ptr=(read_ptr==31)?0:read_ptr+1; end HRDATA = Data;// end end else HRDATA = 32'h0000_0000; end// Detect illegal accesses of larger than 32-bit (HSIZE[2:0] > "010") assign Invalid = ((HREADY == 1'b1 && HSEL == 1'b1 && (HTRANS == `TRN_NONSEQ || HTRANS == `TRN_SEQ) && (HSIZE == `SZ_DWORD || HSIZE[2] == 1'b1)) ? 1'b1 : 1'b0);// Generate first wait-state for two-cycle ERROR response assign HreadyNext = (iHREADYOUT == 1'b0 ? 1'b1 : (Invalid == 1'b1 ? 1'b0 : 1'b1)); always @( negedge (HRESETn) or posedge (HCLK) ) begin if ((!HRESETn)) iHREADYOUT <= 1'b1; else iHREADYOUT <= HreadyNext; end assign HREADYOUT = iHREADYOUT;// An OKAY response is generated for transfers of legal size,// but a two cycle ERROR response is generated if a non-sequential// or sequential transfer is attempted and HSIZE > 32-bit. assign HrespNext = (Invalid == 1'b1 ? `RSP_ERROR : `RSP_OKAY); always @( negedge (HRESETn) or posedge (HCLK) ) begin if ((!HRESETn)) HRESP <= `RSP_OKAY; else begin if (iHREADYOUT) HRESP <= HrespNext; end end/////////////////////////////////endmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -