OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [rtl/] [verilog/] [ram_wb/] [ram_wb.v] - Diff between revs 360 and 412

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 360 Rev 412
module ram_wb ( dat_i, dat_o, adr_i, we_i, sel_i, cyc_i, stb_i, ack_o, cti_i, clk_i, rst_i);
module ram_wb
 
  (
 
   // Inputs
 
   wbm0_adr_i, wbm0_bte_i, wbm0_cti_i, wbm0_cyc_i, wbm0_dat_i, wbm0_sel_i,
 
   wbm0_stb_i, wbm0_we_i,
 
   // Outputs
 
   wbm0_ack_o, wbm0_err_o, wbm0_rty_o, wbm0_dat_o,
 
 
 
   // Inputs
 
   wbm1_adr_i, wbm1_bte_i, wbm1_cti_i, wbm1_cyc_i, wbm1_dat_i, wbm1_sel_i,
 
   wbm1_stb_i, wbm1_we_i,
 
   // Outputs
 
   wbm1_ack_o, wbm1_err_o, wbm1_rty_o, wbm1_dat_o,
 
 
   parameter dat_width = 32;
   // Clock, reset
   parameter adr_width = 12;
   wb_clk_i, wb_rst_i
   parameter mem_size  = 262144; // Default is 1MB (262144 32-bit words)
   );
 
   // Bus parameters
   // wishbone signals
   parameter dw = 32;
   input [31:0]          dat_i;
   parameter aw = 32;
   output [31:0]         dat_o;
   // Memory parameters
   input [adr_width-1:2] adr_i;
   parameter mem_span = 32'h0000_0400;
   input                 we_i;
   parameter adr_width_for_span = 11; //(log2(mem_span));
   input [3:0]            sel_i;
 
   input                 cyc_i;
 
   input                 stb_i;
   input [aw-1:0]        wbm0_adr_i;
   output reg            ack_o;
   input [1:0]           wbm0_bte_i;
   input [2:0]            cti_i;
   input [2:0]           wbm0_cti_i;
 
   input                wbm0_cyc_i;
   // clock
   input [dw-1:0]        wbm0_dat_i;
   input                 clk_i;
   input [3:0]           wbm0_sel_i;
   // async reset
   input                wbm0_stb_i;
   input                 rst_i;
   input                wbm0_we_i;
 
 
   wire [31:0]            wr_data;
   output               wbm0_ack_o;
 
   output               wbm0_err_o;
   // mux for data to ram
   output               wbm0_rty_o;
   assign wr_data[31:24] = sel_i[3] ? dat_i[31:24] : dat_o[31:24];
   output [dw-1:0]       wbm0_dat_o;
   assign wr_data[23:16] = sel_i[2] ? dat_i[23:16] : dat_o[23:16];
 
   assign wr_data[15: 8] = sel_i[1] ? dat_i[15: 8] : dat_o[15: 8];
   input [aw-1:0]        wbm1_adr_i;
   assign wr_data[ 7: 0] = sel_i[0] ? dat_i[ 7: 0] : dat_o[ 7: 0];
   input [1:0]           wbm1_bte_i;
 
   input [2:0]           wbm1_cti_i;
 
   input                wbm1_cyc_i;
 
   input [dw-1:0]        wbm1_dat_i;
 
   input [3:0]           wbm1_sel_i;
 
   input                wbm1_stb_i;
 
   input                wbm1_we_i;
 
 
 
   output               wbm1_ack_o;
 
   output               wbm1_err_o;
 
   output               wbm1_rty_o;
 
   output [dw-1:0]       wbm1_dat_o;
 
 
 
 
 
   input                wb_clk_i;
 
   input                wb_rst_i;
 
 
 
   // Internal wires to actual RAM
 
   wire [aw-1:0]         wb_ram_adr_i;
 
   wire [1:0]            wb_ram_bte_i;
 
   wire [2:0]            wb_ram_cti_i;
 
   wire                 wb_ram_cyc_i;
 
   wire [dw-1:0]         wb_ram_dat_i;
 
   wire [3:0]            wb_ram_sel_i;
 
   wire                 wb_ram_stb_i;
 
   wire                 wb_ram_we_i;
 
 
 
   wire                 wb_ram_ack_o;
 
   wire                 wb_ram_err_o;
 
   wire                 wb_ram_rty_o;
 
   wire [dw-1:0]         wb_ram_dat_o;
 
 
 
   reg [1:0]             input_select, last_selected;
 
   wire                 arb_for_wbm0, arb_for_wbm1;
 
   // Wires allowing selection of new input
 
   assign arb_for_wbm0 = (last_selected[1] | !wbm1_cyc_i) & !(|input_select);
 
   assign arb_for_wbm1 = (last_selected[0] | !wbm0_cyc_i) & !(|input_select);
 
 
 
   // Master select logic
 
   always @(posedge wb_clk_i)
 
     if (wb_rst_i)
 
       input_select <= 0;
 
     else if ((input_select[0] & !wbm0_cyc_i) | (input_select[1] & !wbm1_cyc_i))
 
       input_select <= 0;
 
     else if (!(&input_select) & wbm0_cyc_i & arb_for_wbm0)
 
       input_select <= 2'b01;
 
     else if (!(&input_select) & wbm1_cyc_i & arb_for_wbm1)
 
       input_select <= 2'b10;
 
 
 
   always @(posedge wb_clk_i)
 
     if (wb_rst_i)
 
       last_selected <= 0;
 
     else if (!(&input_select) & wbm0_cyc_i & arb_for_wbm0)
 
       last_selected <= 2'b01;
 
     else if (!(&input_select) & wbm1_cyc_i & arb_for_wbm1)
 
       last_selected <= 2'b10;
 
 
 
   // Mux input signals to RAM (default to wbm0)
 
   assign wb_ram_adr_i = (input_select[1]) ? wbm1_adr_i :
 
                         (input_select[0]) ? wbm0_adr_i : 0;
 
   assign wb_ram_bte_i = (input_select[1]) ? wbm1_bte_i :
 
                         (input_select[0]) ? wbm0_bte_i : 0;
 
   assign wb_ram_cti_i = (input_select[1]) ? wbm1_cti_i :
 
                         (input_select[0]) ? wbm0_cti_i : 0;
 
   assign wb_ram_cyc_i = (input_select[1]) ? wbm1_cyc_i :
 
                         (input_select[0]) ? wbm0_cyc_i : 0;
 
   assign wb_ram_dat_i = (input_select[1]) ? wbm1_dat_i :
 
                         (input_select[0]) ? wbm0_dat_i : 0;
 
   assign wb_ram_sel_i = (input_select[1]) ? wbm1_sel_i :
 
                         (input_select[0]) ? wbm0_sel_i : 0;
 
   assign wb_ram_stb_i = (input_select[1]) ? wbm1_stb_i :
 
                         (input_select[0]) ? wbm0_stb_i : 0;
 
   assign wb_ram_we_i  = (input_select[1]) ? wbm1_we_i  :
 
                         (input_select[0]) ? wbm0_we_i : 0;
 
 
 
   // Output from RAM, gate the ACK, ERR, RTY signals appropriately
 
   assign wbm0_dat_o = wb_ram_dat_o;
 
   assign wbm0_ack_o = wb_ram_ack_o & input_select[0];
 
   assign wbm0_err_o = wb_ram_err_o & input_select[0];
 
   assign wbm0_rty_o = wb_ram_rty_o & input_select[0];
 
 
 
   assign wbm1_dat_o = wb_ram_dat_o;
 
   assign wbm1_ack_o = wb_ram_ack_o & input_select[1];
 
   assign wbm1_err_o = wb_ram_err_o & input_select[1];
 
   assign wbm1_rty_o = wb_ram_rty_o & input_select[1];
 
 
   ram_wb_sc_sw
   ram_wb_b3 ram_wb_b3_0
     #
 
     (
     (
      .dat_width(dat_width),
      // Outputs
      .adr_width(adr_width),
      .wb_ack_o                         (wb_ram_ack_o),
      .mem_size(mem_size)
      .wb_err_o                         (wb_ram_err_o),
      )
      .wb_rty_o                         (wb_ram_rty_o),
     ram0
      .wb_dat_o                         (wb_ram_dat_o),
     (
      // Inputs
      .dat_i(wr_data),
      .wb_adr_i                         (wb_ram_adr_i),
      .dat_o(dat_o),
      .wb_bte_i                         (wb_ram_bte_i),
      .adr_i({2'b00, adr_i}),
      .wb_cti_i                         (wb_ram_cti_i),
      .we_i(we_i & ack_o),
      .wb_cyc_i                         (wb_ram_cyc_i),
      .clk(clk_i)
      .wb_dat_i                         (wb_ram_dat_i),
      );
      .wb_sel_i                         (wb_ram_sel_i),
 
      .wb_stb_i                         (wb_ram_stb_i),
 
      .wb_we_i                          (wb_ram_we_i),
 
      .wb_clk_i                         (wb_clk_i),
 
      .wb_rst_i                         (wb_rst_i));
 
 
 
   defparam ram_wb_b3_0.aw = aw;
 
   defparam ram_wb_b3_0.dw = dw;
 
   defparam ram_wb_b3_0.mem_span = mem_span;
 
   defparam ram_wb_b3_0.adr_width_for_span = adr_width_for_span;
 
 
   // ack_o
endmodule // ram_wb
   always @ (posedge clk_i or posedge rst_i)
 
     if (rst_i)
 
       ack_o <= 1'b0;
 
     else
 
       if (!ack_o)
 
         begin
 
            if (cyc_i & stb_i)
 
              ack_o <= 1'b1;
 
         end
 
       else
 
         ack_o <= 1'b0;
 
 
 
   // We did have acking logic which was sensitive to the
 
   // burst signals, cti_i, but this proved to cause problems
 
   // and we were never receiving back-to-back reads or writes
 
   // anyway. This logic which only acks one transaction at a
 
   // time appears to work well, despite not supporting burst
 
   // transactions.
 
 
 
endmodule
 
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.