//====================================================================== // // blockmem_rw32ptr_r64.v // ---------------------- // Synchronous block memory with two separate ports. Port one is // called the api port and port two is called the internal port. // // The api port contains its own address generator and the api port // uses 32 bit data width. The address is automatically increased when // the cs signal is set. The address is reset to zero when the rst // signal is asserted. // // The second data port is called the internal port. The internal // port uses 64 bit data width. // // and an internal port. The api port contains apointer // and 32 bit data width. The internal port // For port 1 the address is implicit and instead given by the // internal pointer. // Redistribution and use in source and binary forms, with or // without modification, are permitted provided that the following // conditions are met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in // the documentation and/or other materials provided with the // distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //====================================================================== module blockmem_rw32ptr_r64( input wire clk, input wire reset_n, input wire api_rst, input wire api_cs, input wire api_wr, input wire [31 : 0] api_wr_data, output wire [31 : 0] api_rd_data, input wire [06 : 0] internal_addr, output wire [63 : 0] internal_rd_data ); //---------------------------------------------------------------- // Regs and memories. //---------------------------------------------------------------- reg [31 : 0] mem0 [0 : 127]; wire mem0_we; reg [31 : 0] mem1 [0 : 127]; wire mem1_we; reg [7 : 0] ptr_reg; reg [7 : 0] ptr_new; reg ptr_we; //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- reg [31 : 0] tmp0_api_rd_data; reg [31 : 0] tmp1_api_rd_data; reg [31 : 0] tmp0_int_rd_data; reg [31 : 0] tmp1_int_rd_data; //---------------------------------------------------------------- // Assignments. //---------------------------------------------------------------- assign api_rd_data = ptr_reg[0] ? tmp1_api_rd_data : tmp0_api_rd_data; assign internal_rd_data = {tmp1_int_rd_data, tmp0_int_rd_data}; assign mem0_we = api_wr & ~ptr_reg[0]; assign mem1_we = api_wr & ptr_reg[0]; //---------------------------------------------------------------- // mem0_updates //---------------------------------------------------------------- always @ (posedge clk) begin : update_mem0 if (mem0_we) mem0[ptr_reg[7 : 1]] <= api_wr_data; tmp0_api_rd_data <= mem0[ptr_reg[7 : 1]]; tmp0_int_rd_data <= mem0[internal_addr]; end always @ (posedge clk) begin : update_mem1 if (mem1_we) mem1[ptr_reg[7 : 1]] <= api_wr_data; tmp1_api_rd_data <= mem1[ptr_reg[7 : 1]]; tmp1_int_rd_data <= mem1[internal_addr]; end //---------------------------------------------------------------- // reg_update //---------------------------------------------------------------- always @ (posedge clk or negedge reset_n) begin : reg_update if (!reset_n) ptr_reg <= 8'h00; else if (ptr_we) ptr_reg <= ptr_new; end //---------------------------------------------------------------- // ptr_logic //---------------------------------------------------------------- always @* begin : ptr_logic ptr_new = 8'h00; ptr_we = 1'b0; if (api_rst) begin ptr_new = 8'h00; ptr_we = 1'b1; end if (api_cs) begin ptr_new = ptr_reg + 1'b1; ptr_we = 1'b1; end end endmodule // blockmem_rw32ptr_r64 //====================================================================== // EOF blockmem_rw32ptr_r64 //======================================================================