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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [rtl/] [verilog/] [wb_ram_b3/] [wb_ram_b3.v] - Diff between revs 362 and 363

Only display areas with differences | Details | Blame | View Log

Rev 362 Rev 363
 
 
// Version 5
// Version 5
 
 
//`define RANDOM_ACK_NEGATION
//`define RANDOM_ACK_NEGATION
 
 
module wb_ram_b3(
module wb_ram_b3(
                 wb_adr_i, wb_bte_i, wb_cti_i, wb_cyc_i, wb_dat_i, wb_sel_i,
                 wb_adr_i, wb_bte_i, wb_cti_i, wb_cyc_i, wb_dat_i, wb_sel_i,
                 wb_stb_i, wb_we_i,
                 wb_stb_i, wb_we_i,
 
 
                 wb_ack_o, wb_err_o, wb_rty_o, wb_dat_o,
                 wb_ack_o, wb_err_o, wb_rty_o, wb_dat_o,
 
 
                 wb_clk_i, wb_rst_i);
                 wb_clk_i, wb_rst_i);
 
 
   // Memory parameters
   // Memory parameters
   parameter dw = 32;
   parameter dw = 32;
 
 
   // 32MB memory by default
   // 32MB memory by default
   parameter aw = 25;
   parameter aw = 23;
   parameter mem_size  = 8388608;
   parameter mem_size  = 8388608;
 
 
   input [aw-1:0]        wb_adr_i;
   input [aw-1:0]        wb_adr_i;
   input [1:0]           wb_bte_i;
   input [1:0]           wb_bte_i;
   input [2:0]           wb_cti_i;
   input [2:0]           wb_cti_i;
   input                wb_cyc_i;
   input                wb_cyc_i;
   input [dw-1:0]        wb_dat_i;
   input [dw-1:0]        wb_dat_i;
   input [3:0]           wb_sel_i;
   input [3:0]           wb_sel_i;
   input                wb_stb_i;
   input                wb_stb_i;
   input                wb_we_i;
   input                wb_we_i;
 
 
   output               wb_ack_o;
   output               wb_ack_o;
   output               wb_err_o;
   output               wb_err_o;
   output               wb_rty_o;
   output               wb_rty_o;
   output [dw-1:0]       wb_dat_o;
   output [dw-1:0]       wb_dat_o;
 
 
   input                wb_clk_i;
   input                wb_clk_i;
   input                wb_rst_i;
   input                wb_rst_i;
 
 
 
 
   // synthesis attribute ram_style of mem is block
   // synthesis attribute ram_style of mem is block
   reg [dw-1:0]  mem [ 0 : mem_size-1 ]  /* verilator public */ /* synthesis ram_style = no_rw_check */;
   reg [dw-1:0]  mem [ 0 : mem_size-1 ]  /* verilator public */ /* synthesis ram_style = no_rw_check */;
 
 
   //reg [aw-1:2] wb_adr_i_r;
   //reg [aw-1:2] wb_adr_i_r;
   reg [(aw-2)-1:0] adr;
   reg [aw-1:0] adr;
 
 
   wire [31:0]                      wr_data;
   wire [31:0]                      wr_data;
 
 
   // Register to indicate if the cycle is a Wishbone B3-registered feedback 
   // Register to indicate if the cycle is a Wishbone B3-registered feedback 
   // type access
   // type access
   reg                             wb_b3_trans;
   reg                             wb_b3_trans;
   wire                            wb_b3_trans_start, wb_b3_trans_stop;
   wire                            wb_b3_trans_start, wb_b3_trans_stop;
 
 
   // Register to use for counting the addresses when doing burst accesses
   // Register to use for counting the addresses when doing burst accesses
   reg [aw-1-2:0]  burst_adr_counter;
   reg [aw-1:0]  burst_adr_counter;
   reg [2:0]                        wb_cti_i_r;
   reg [2:0]                        wb_cti_i_r;
   reg [1:0]                        wb_bte_i_r;
   reg [1:0]                        wb_bte_i_r;
   wire                            using_burst_adr;
   wire                            using_burst_adr;
   wire                            burst_access_wrong_wb_adr;
   wire                            burst_access_wrong_wb_adr;
 
 
   reg                             random_ack_negate;
   reg                             random_ack_negate;
 
 
   // Logic to detect if there's a burst access going on
   // Logic to detect if there's a burst access going on
   assign wb_b3_trans_start = ((wb_cti_i == 3'b001)|(wb_cti_i == 3'b010)) &
   assign wb_b3_trans_start = ((wb_cti_i == 3'b001)|(wb_cti_i == 3'b010)) &
                              wb_stb_i & !wb_b3_trans;
                              wb_stb_i & !wb_b3_trans;
 
 
   assign  wb_b3_trans_stop = (wb_cti_i == 3'b111) &
   assign  wb_b3_trans_stop = (wb_cti_i == 3'b111) &
                              wb_stb_i & wb_b3_trans & wb_ack_o;
                              wb_stb_i & wb_b3_trans & wb_ack_o;
 
 
   always @(posedge wb_clk_i)
   always @(posedge wb_clk_i)
     if (wb_rst_i)
     if (wb_rst_i)
       wb_b3_trans <= 0;
       wb_b3_trans <= 0;
     else if (wb_b3_trans_start)
     else if (wb_b3_trans_start)
       wb_b3_trans <= 1;
       wb_b3_trans <= 1;
     else if (wb_b3_trans_stop)
     else if (wb_b3_trans_stop)
       wb_b3_trans <= 0;
       wb_b3_trans <= 0;
 
 
   // Burst address generation logic
   // Burst address generation logic
   always @*
   always @*
     if (wb_rst_i)
     if (wb_rst_i)
       burst_adr_counter = 0;
       burst_adr_counter = 0;
     else if (wb_b3_trans_start)
     else if (wb_b3_trans_start)
       burst_adr_counter = wb_adr_i[aw-1:2];
       burst_adr_counter = {2'b00,wb_adr_i[aw-1:2]};
     else if ((wb_cti_i_r == 3'b010) & wb_ack_o & wb_b3_trans)
     else if ((wb_cti_i_r == 3'b010) & wb_ack_o & wb_b3_trans)
       // Incrementing burst
       // Incrementing burst
       begin
       begin
          if (wb_bte_i_r == 2'b00) // Linear burst
          if (wb_bte_i_r == 2'b00) // Linear burst
            burst_adr_counter = adr + 1;
            burst_adr_counter = adr + 1;
          if (wb_bte_i_r == 2'b01) // 4-beat wrap burst
          if (wb_bte_i_r == 2'b01) // 4-beat wrap burst
            burst_adr_counter[1:0] = adr[1:0] + 1;
            burst_adr_counter[1:0] = adr[1:0] + 1;
          if (wb_bte_i_r == 2'b10) // 8-beat wrap burst
          if (wb_bte_i_r == 2'b10) // 8-beat wrap burst
            burst_adr_counter[2:0] = adr[2:0] + 1;
            burst_adr_counter[2:0] = adr[2:0] + 1;
          if (wb_bte_i_r == 2'b11) // 16-beat wrap burst
          if (wb_bte_i_r == 2'b11) // 16-beat wrap burst
            burst_adr_counter[3:0] = adr[3:0] + 1;
            burst_adr_counter[3:0] = adr[3:0] + 1;
       end // if ((wb_cti_i_r == 3'b010) & wb_ack_o_r)
       end // if ((wb_cti_i_r == 3'b010) & wb_ack_o_r)
     else if (!wb_ack_o & wb_b3_trans)
     else if (!wb_ack_o & wb_b3_trans)
            burst_adr_counter = adr;
            burst_adr_counter = adr;
 
 
 
 
   always @(posedge wb_clk_i)
   always @(posedge wb_clk_i)
     wb_bte_i_r <= wb_bte_i;
     wb_bte_i_r <= wb_bte_i;
 
 
   // Register it locally
   // Register it locally
   always @(posedge wb_clk_i)
   always @(posedge wb_clk_i)
     wb_cti_i_r <= wb_cti_i;
     wb_cti_i_r <= wb_cti_i;
 
 
   assign using_burst_adr = wb_b3_trans;
   assign using_burst_adr = wb_b3_trans;
 
 
   assign burst_access_wrong_wb_adr = (using_burst_adr & (adr != wb_adr_i[aw-1:2]));
   assign burst_access_wrong_wb_adr = (using_burst_adr & (adr != {2'b00,wb_adr_i[aw-1:2]}));
 
 
   // Address registering logic
   // Address registering logic
   always@(posedge wb_clk_i)
   always@(posedge wb_clk_i)
     if(wb_rst_i)
     if(wb_rst_i)
       adr <= 0;
       adr <= 0;
     else if (using_burst_adr)
     else if (using_burst_adr)
       adr <= burst_adr_counter;
       adr <= burst_adr_counter;
     else if (wb_cyc_i & wb_stb_i)
     else if (wb_cyc_i & wb_stb_i)
       adr <= wb_adr_i[aw-1:2];
       adr <= {2'b00,wb_adr_i[aw-1:2]};
 
 
   parameter memory_file = "sram.vmem";
   parameter memory_file = "sram.vmem";
 
 
 
 
`ifdef verilator
`ifdef verilator
 
 
   task do_readmemh;
   task do_readmemh;
      // verilator public
      // verilator public
      $readmemh(memory_file, mem);
      $readmemh(memory_file, mem);
   endtask // do_readmemh
   endtask // do_readmemh
 
 
`else
`else
 
 
   initial
   initial
     begin
     begin
        $readmemh(memory_file, mem);
        $readmemh(memory_file, mem);
     end
     end
 
 
`endif // !`ifdef verilator
`endif // !`ifdef verilator
 
 
 
 
   // Function to access RAM (for use by Verilator).
   // Function to access RAM (for use by Verilator).
   function [31:0] get_mem;
   function [31:0] get_mem;
      // verilator public
      // verilator public
      input [aw-1:0]             addr;
      input [aw-1:0]             addr;
      get_mem = mem[addr];
      get_mem = mem[addr];
   endfunction // get_mem
   endfunction // get_mem
 
 
   // Function to write RAM (for use by Verilator).
   // Function to write RAM (for use by Verilator).
   function set_mem;
   function set_mem;
      // verilator public
      // verilator public
      input [aw-1:0]             addr;
      input [aw-1:0]             addr;
      input [dw-1:0]             data;
      input [dw-1:0]             data;
      mem[addr] = data;
      mem[addr] = data;
   endfunction // set_mem
   endfunction // set_mem
 
 
 
 
   assign wb_rty_o = 0;
   assign wb_rty_o = 0;
 
 
   // mux for data to ram, RMW on part sel != 4'hf
   // mux for data to ram, RMW on part sel != 4'hf
   assign wr_data[31:24] = wb_sel_i[3] ? wb_dat_i[31:24] : wb_dat_o[31:24];
   assign wr_data[31:24] = wb_sel_i[3] ? wb_dat_i[31:24] : wb_dat_o[31:24];
   assign wr_data[23:16] = wb_sel_i[2] ? wb_dat_i[23:16] : wb_dat_o[23:16];
   assign wr_data[23:16] = wb_sel_i[2] ? wb_dat_i[23:16] : wb_dat_o[23:16];
   assign wr_data[15: 8] = wb_sel_i[1] ? wb_dat_i[15: 8] : wb_dat_o[15: 8];
   assign wr_data[15: 8] = wb_sel_i[1] ? wb_dat_i[15: 8] : wb_dat_o[15: 8];
   assign wr_data[ 7: 0] = wb_sel_i[0] ? wb_dat_i[ 7: 0] : wb_dat_o[ 7: 0];
   assign wr_data[ 7: 0] = wb_sel_i[0] ? wb_dat_i[ 7: 0] : wb_dat_o[ 7: 0];
 
 
   // Address logic
   // Address logic
   /*
   /*
   always @(posedge wb_clk_i)
   always @(posedge wb_clk_i)
     begin
     begin
        if (wb_rst_i)
        if (wb_rst_i)
          wb_adr_i_r <= 0;
          wb_adr_i_r <= 0;
        else
        else
          if (wb_cyc_i & wb_stb_i)
          if (wb_cyc_i & wb_stb_i)
            wb_adr_i_r <= wb_adr_i[aw-1:2];
            wb_adr_i_r <= wb_adr_i[aw-1:2];
     end
     end
    */
    */
 
 
   wire ram_we;
   wire ram_we;
   assign ram_we = wb_we_i & wb_ack_o;
   assign ram_we = wb_we_i & wb_ack_o;
 
 
   assign wb_dat_o = mem[adr];
   assign wb_dat_o = mem[adr];
 
 
   // Write logic
   // Write logic
   always @ (posedge wb_clk_i)
   always @ (posedge wb_clk_i)
     begin
     begin
        if (ram_we)
        if (ram_we)
          mem[adr] <= wr_data;
          mem[adr] <= wr_data;
     end
     end
 
 
   // Ack Logic
   // Ack Logic
   reg wb_ack_o_r;
   reg wb_ack_o_r;
 
 
   assign wb_ack_o = wb_ack_o_r & wb_stb_i;
   assign wb_ack_o = wb_ack_o_r & wb_stb_i;
 
 
   always @(posedge wb_clk_i)
   always @(posedge wb_clk_i)
     if (wb_rst_i)
     if (wb_rst_i)
       begin
       begin
          wb_ack_o_r <= 1'b0;
          wb_ack_o_r <= 1'b0;
       end
       end
     else if (wb_cyc_i) // We have bus
     else if (wb_cyc_i) // We have bus
       begin
       begin
          if (wb_cti_i == 3'b111)
          if (wb_cti_i == 3'b111)
            begin
            begin
               // End of burst
               // End of burst
               if (wb_ack_o_r)
               if (wb_ack_o_r)
                 // ALWAYS de-assert ack after burst end
                 // ALWAYS de-assert ack after burst end
                 wb_ack_o_r <= 0;
                 wb_ack_o_r <= 0;
               else if (wb_stb_i & !random_ack_negate)
               else if (wb_stb_i & !random_ack_negate)
                 wb_ack_o_r <= 1;
                 wb_ack_o_r <= 1;
               else
               else
                 wb_ack_o_r <= 0;
                 wb_ack_o_r <= 0;
            end
            end
          else if (wb_cti_i == 3'b000)
          else if (wb_cti_i == 3'b000)
            begin
            begin
               // Classic cycle acks
               // Classic cycle acks
               if (wb_stb_i & !random_ack_negate)
               if (wb_stb_i & !random_ack_negate)
                 begin
                 begin
                    if (!wb_ack_o_r)
                    if (!wb_ack_o_r)
                      wb_ack_o_r <= 1;
                      wb_ack_o_r <= 1;
                    else
                    else
                      wb_ack_o_r <= 0;
                      wb_ack_o_r <= 0;
                 end
                 end
               else
               else
                 wb_ack_o_r <= 0;
                 wb_ack_o_r <= 0;
            end // if (wb_cti_i == 3'b000)
            end // if (wb_cti_i == 3'b000)
          else if ((wb_cti_i == 3'b001) | (wb_cti_i == 3'b010))
          else if ((wb_cti_i == 3'b001) | (wb_cti_i == 3'b010))
            begin
            begin
               // Increment/constant address bursts
               // Increment/constant address bursts
               if (wb_stb_i & !random_ack_negate)
               if (wb_stb_i & !random_ack_negate)
                 wb_ack_o_r <= 1;
                 wb_ack_o_r <= 1;
               else
               else
                 wb_ack_o_r <= 0;
                 wb_ack_o_r <= 0;
            end
            end
          else if (wb_cti_i == 3'b111)
          else if (wb_cti_i == 3'b111)
            begin
            begin
               // End of cycle
               // End of cycle
               if (wb_stb_i & !random_ack_negate)
               if (wb_stb_i & !random_ack_negate)
                 wb_ack_o_r <= 1;
                 wb_ack_o_r <= 1;
               else
               else
                 wb_ack_o_r <= 0;
                 wb_ack_o_r <= 0;
            end
            end
       end // if (wb_cyc_i)
       end // if (wb_cyc_i)
     else
     else
       wb_ack_o_r <= 0;
       wb_ack_o_r <= 0;
 
 
   assign wb_err_o = 1'b0;// wb_ack_o & (burst_access_wrong_wb_adr); // OR in other errors here
   assign wb_err_o = 1'b0;// wb_ack_o & (burst_access_wrong_wb_adr); // OR in other errors here
 
 
 
 
   // Random ACK negation logic
   // Random ACK negation logic
`ifdef RANDOM_ACK_NEGATION
`ifdef RANDOM_ACK_NEGATION
   reg [31:0] lfsr;
   reg [31:0] lfsr;
   always @(posedge wb_clk_i)
   always @(posedge wb_clk_i)
     if (wb_rst_i)
     if (wb_rst_i)
       lfsr <= 32'h273e2d4a;
       lfsr <= 32'h273e2d4a;
     else lfsr <= {lfsr[30:0], ~(lfsr[30]^lfsr[6]^lfsr[4]^lfsr[1]^lfsr[0])};
     else lfsr <= {lfsr[30:0], ~(lfsr[30]^lfsr[6]^lfsr[4]^lfsr[1]^lfsr[0])};
 
 
   always @(posedge wb_clk_i)
   always @(posedge wb_clk_i)
     random_ack_negate <= lfsr[26];
     random_ack_negate <= lfsr[26];
 
 
`else
`else
   always @(wb_rst_i)
   always @(wb_rst_i)
     random_ack_negate = 0;
     random_ack_negate = 0;
`endif
`endif
 
 
 
 
 
 
endmodule // wb_ram_b3_v2
endmodule // wb_ram_b3_v2
 
 
 
 

powered by: WebSVN 2.1.0

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