URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [branches/] [mp3_stable/] [mp3/] [rtl/] [verilog/] [mem_if/] [sram_top.v] - Rev 1765
Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// MP3 demo SRAM interface //// //// //// //// This file is part of the MP3 demo application //// //// http://www.opencores.org/cores/or1k/mp3/ //// //// //// //// Description //// //// Connects MP3 demo to SRAM. It does RMW for byte accesses //// //// because XSV board has WEs on a 16-bit basis. //// //// //// //// To Do: //// //// - nothing really //// //// //// //// Author(s): //// //// - Simon Srot, simons@opencores.org //// //// - Igor Mohor, igorm@opencores.org //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2001 Authors //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source is distributed in the hope that it will be //// //// useful, but WITHOUT ANY WARRANTY; without even the implied //// //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// //// PURPOSE. See the GNU Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from http://www.opencores.org/lgpl.shtml //// //// //// ////////////////////////////////////////////////////////////////////// // // CVS Revision History // // $Log: not supported by cvs2svn $ // // synopsys translate_off `include "timescale.v" // synopsys translate_on module sram_top ( clk, rstn, wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i, wb_stb_i, wb_ack_o, wb_err_o, r_cen, r0_wen, r1_wen, r_oen, r_a, r_d, l_cen, l0_wen, l1_wen, l_oen, l_a, l_d ); parameter addr_width = 19; input clk; input rstn; input [31:0] wb_dat_i; output [31:0] wb_dat_o; input [31:0] wb_adr_i; input [3:0] wb_sel_i; input wb_we_i; input wb_cyc_i; input wb_stb_i; output wb_ack_o; output wb_err_o; output r_oen; output r0_wen; output r1_wen; output r_cen; inout [15:0] r_d; output [addr_width-1:0] r_a; output l_oen; output l0_wen; output l1_wen; output l_cen; inout [15:0] l_d; output [addr_width-1:0] l_a; reg [15:0] r_data; reg [15:0] l_data; reg l0_wen; wire l1_wen = l0_wen; reg r0_wen; wire r1_wen = r0_wen; reg [31:0] latch_data; reg ack_we; wire l_oe; wire r_oe; assign l_oen = ~l_oe; assign r_oen = ~r_oe; reg Mux; always @ (negedge clk or negedge rstn) begin if(~rstn) Mux <= 1'b0; else if(ack_we) Mux <= #1 1'b1; else Mux <= #1 1'b0; end reg [addr_width-1:0] LatchedAddr; always @ (negedge clk or negedge rstn) begin if(~rstn) LatchedAddr <= 'h0; else if(wb_cyc_i & wb_stb_i) LatchedAddr <= #1 wb_adr_i[addr_width+1:2]; end assign l_a = Mux? LatchedAddr : wb_adr_i[addr_width+1:2]; assign r_a = l_a; reg [15:0] l_read; reg [15:0] r_read; // Data latch from RAM (read data) always @ (posedge clk or negedge rstn) begin if(~rstn) begin l_read <= 16'h0; r_read <= 16'h0; end else if(wb_cyc_i & wb_stb_i) begin l_read <= #1 l_d[15:0]; r_read <= #1 r_d[15:0]; end end assign wb_dat_o = {r_d, l_d}; // Mux and latch data for writing (bytes 0 and 1) reg [15:0] l_mux; always @ (negedge clk or negedge rstn) begin if(~rstn) l_mux <= 16'h0; else if(~l0_wen) begin if(wb_sel_i[0]) l_mux[7:0] <= #1 wb_dat_i[7:0]; else l_mux[7:0] <= #1 l_read[7:0]; if(wb_sel_i[1]) l_mux[15:8] <= #1 wb_dat_i[15:8]; else l_mux[15:8] <= #1 l_read[15:8]; end else l_mux[15:0] <= #1 16'hz; end // Mux and latch data for writing (bytes 2 and 3) reg [15:0] r_mux; always @ (negedge clk or negedge rstn) begin if(~rstn) r_mux <= 16'h0; else if(~r0_wen) begin if(wb_sel_i[2]) r_mux[7:0] <= #1 wb_dat_i[23:16]; else r_mux[7:0] <= #1 r_read[7:0]; if(wb_sel_i[3]) r_mux[15:8] <= #1 wb_dat_i[31:24]; else r_mux[15:8] <= #1 r_read[15:8]; end else r_mux <= #1 16'hz; end assign l_d = l_mux; assign r_d = r_mux; // Output enable assign l_oe = wb_cyc_i & wb_stb_i & l0_wen; assign r_oe = wb_cyc_i & wb_stb_i & r0_wen; // WE always @ (posedge clk or negedge rstn) begin if(~rstn) l0_wen <= 1'b1; else if(wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[1:0]) & ~wb_ack_o) l0_wen <= #1 1'b0; else l0_wen <= 1'b1; end // WE always @ (posedge clk or negedge rstn) begin if(~rstn) r0_wen <= 1'b1; else if(wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[3:2]) & ~wb_ack_o) r0_wen <= #1 1'b0; else r0_wen <= 1'b1; end // CE assign l_cen = ~(wb_cyc_i & wb_stb_i); assign r_cen = l_cen; always @ (posedge clk or negedge rstn) begin if(~rstn) ack_we <= 1'b0; else if(wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we) ack_we <= #1 1'b1; else ack_we <= #1 1'b0; end assign wb_ack_o = (wb_cyc_i & wb_stb_i & ~wb_we_i) | ack_we; assign wb_err_o = 1'b0; // synopsys translate_off integer fsram; initial fsram = $fopen("sram.log"); always @(posedge clk) begin if (~l0_wen | ~r0_wen) $fdisplay(fsram, "%t [%h] <- write %h", $time, wb_adr_i, {r_d, l_d}); else if(l_oe | r_oe) $fdisplay(fsram, "%t [%h] -> read %h", $time, wb_adr_i, {r_d, l_d}); end // synopsys translate_on endmodule