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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1200/] [rtl/] [verilog/] [or1200_dc_fsm.v] - Diff between revs 364 and 481

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 364 Rev 481
Line 123... Line 123...
   //
   //
   // Internal wires and regs
   // Internal wires and regs
   //
   //
   reg [31:0]                            addr_r;
   reg [31:0]                            addr_r;
   reg [2:0]                             state;
   reg [2:0]                             state;
   reg [2:0]                             cnt;
   reg [`OR1200_DCLS-1:0]                cnt;
   reg                                  hitmiss_eval;
   reg                                  hitmiss_eval;
   reg                                  store;
   reg                                  store;
   reg                                  load;
   reg                                  load;
   reg                                  cache_inhibit;
   reg                                  cache_inhibit;
   reg                                  cache_miss;
   reg                                  cache_miss;
Line 148... Line 148...
   wire                                 dcram_we_during_line_load;
   wire                                 dcram_we_during_line_load;
   wire                                 tagram_we_end_of_loadstore_loop;
   wire                                 tagram_we_end_of_loadstore_loop;
   wire                                 tagram_dirty_bit_set;
   wire                                 tagram_dirty_bit_set;
   wire                                 writethrough;
   wire                                 writethrough;
   wire                                 cache_inhibit_with_eval;
   wire                                 cache_inhibit_with_eval;
   wire [1:0]                            next_addr_word;
   wire [(`OR1200_DCLS-1)-2:0]           next_addr_word;
 
 
   //
   //
   // Cache inhibit
   // Cache inhibit
   //
   //
 
 
Line 266... Line 266...
   assign dcram_di_sel = load;
   assign dcram_di_sel = load;
   // Data to external bus - always from IU except in case of bursting back
   // Data to external bus - always from IU except in case of bursting back
   //                        the line to memory. (1 selects DCRAM)
   //                        the line to memory. (1 selects DCRAM)
   assign biu_do_sel = (state == `OR1200_DCFSM_LOOP2) & store;
   assign biu_do_sel = (state == `OR1200_DCFSM_LOOP2) & store;
 
 
   // 2-bit wire for calculating next word of burst write
   // 3-bit wire for calculating next word of burst write, depending on
   assign next_addr_word = addr_r[3:2] + 1;
   // line size of data cache.
 
   assign next_addr_word =  addr_r[`OR1200_DCLS-1:2] + 1;
 
 
   // Address to cache RAM (tag address also derived from this)   
   // Address to cache RAM (tag address also derived from this)   
   assign dc_addr =
   assign dc_addr =
                   // First check if we've got a block flush or WB op
                   // First check if we've got a block flush or WB op
                   ((dc_block_flush & !cache_spr_block_flush) |
                   ((dc_block_flush & !cache_spr_block_flush) |
Line 283... Line 284...
                    // Next, if in writeback loop, when ACKed must immediately
                    // Next, if in writeback loop, when ACKed must immediately
                    // output next word address (the RAM address takes a cycle
                    // output next word address (the RAM address takes a cycle
                    // to increment, but it's needed immediately for burst)
                    // to increment, but it's needed immediately for burst)
                    // otherwise, output our registered address.
                    // otherwise, output our registered address.
                    (state==`OR1200_DCFSM_LOOP2 & biudata_valid & store ) ?
                    (state==`OR1200_DCFSM_LOOP2 & biudata_valid & store ) ?
                    {addr_r[31:4], next_addr_word, 2'b00} : addr_r;
                    {addr_r[31:`OR1200_DCLS], next_addr_word, 2'b00} : addr_r;
 
 
`ifdef OR1200_DC_WRITETHROUGH
`ifdef OR1200_DC_WRITETHROUGH
 `ifdef OR1200_DC_NOSTACKWRITETHROUGH
 `ifdef OR1200_DC_NOSTACKWRITETHROUGH
   assign writethrough = !dc_no_writethrough;
   assign writethrough = !dc_no_writethrough;
 `else
 `else
Line 340... Line 341...
   // Get the _early_ ack on first ACK back from wishbone during load only
   // Get the _early_ ack on first ACK back from wishbone during load only
   // Condition is that we're in the loop - that it's the first ack we get (can
   // Condition is that we're in the loop - that it's the first ack we get (can
   // tell from value of cnt), and we're loading a line to read from it (not
   // tell from value of cnt), and we're loading a line to read from it (not
   // loading to write to it, in the case of a write without writethrough.)
   // loading to write to it, in the case of a write without writethrough.)
   assign load_miss_ack =  ((state== `OR1200_DCFSM_LOOP2) & load &
   assign load_miss_ack =  ((state== `OR1200_DCFSM_LOOP2) & load &
                             (cnt==`OR1200_DCLS-1) & biudata_valid &
                            (cnt==((1 << `OR1200_DCLS) - 4)) & biudata_valid &
                            !(dcqmem_we_i & !writethrough));
                            !(dcqmem_we_i & !writethrough));
 
 
   assign load_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
   assign load_inhibit_ack = (state == `OR1200_DCFSM_CLOADSTORE) &
                             load & cache_inhibit & biudata_valid;
                             load & cache_inhibit & biudata_valid;
 
 
Line 360... Line 361...
   // Main DC FSM
   // Main DC FSM
   //
   //
   always @(posedge clk or `OR1200_RST_EVENT rst) begin
   always @(posedge clk or `OR1200_RST_EVENT rst) begin
      if (rst == `OR1200_RST_VALUE) begin
      if (rst == `OR1200_RST_VALUE) begin
         state <=  `OR1200_DCFSM_IDLE;
         state <=  `OR1200_DCFSM_IDLE;
         addr_r <=  32'b0;
         addr_r <=  32'd0;
         hitmiss_eval <=  1'b0;
         hitmiss_eval <=  1'b0;
         store <=  1'b0;
         store <=  1'b0;
         load <=  1'b0;
         load <=  1'b0;
         cnt <=  3'd0;
         cnt <=  `OR1200_DCLS'd0;
         cache_miss <=  1'b0;
         cache_miss <=  1'b0;
         cache_dirty_needs_writeback <= 1'b0;
         cache_dirty_needs_writeback <= 1'b0;
         cache_inhibit <=  1'b0;
         cache_inhibit <=  1'b0;
         did_early_load_ack <= 1'b0;
         did_early_load_ack <= 1'b0;
         cache_spr_block_flush <= 1'b0;
         cache_spr_block_flush <= 1'b0;
Line 428... Line 429...
                     load <= 1'b1;
                     load <= 1'b1;
                     store <= 1'b0;
                     store <= 1'b0;
                  end // else: !if(dirty)
                  end // else: !if(dirty)
                  state <= `OR1200_DCFSM_LOOP2;
                  state <= `OR1200_DCFSM_LOOP2;
                  // Set the counter for the burst accesses
                  // Set the counter for the burst accesses
                  cnt <=  `OR1200_DCLS-1;
                  cnt <=  ((1 << `OR1200_DCLS) - 4);
               end
               end
             else if (// Strobe goes low
             else if (// Strobe goes low
                      !dcqmem_cycstb_i |
                      !dcqmem_cycstb_i |
                      // Cycle finishes
                      // Cycle finishes
                      (!hitmiss_eval & (biudata_valid | biudata_error)) |
                      (!hitmiss_eval & (biudata_valid | biudata_error)) |
Line 451... Line 452...
          `OR1200_DCFSM_LOOP2 : begin // loop/abort          
          `OR1200_DCFSM_LOOP2 : begin // loop/abort          
             if (!dc_en| biudata_error) begin
             if (!dc_en| biudata_error) begin
                state <=  `OR1200_DCFSM_IDLE;
                state <=  `OR1200_DCFSM_IDLE;
                load <=  1'b0;
                load <=  1'b0;
                store <= 1'b0;
                store <= 1'b0;
                cnt <= 3'd0;
                cnt <= `OR1200_DCLS'd0;
             end
             end
             if (biudata_valid & (|cnt)) begin
             if (biudata_valid & (|cnt)) begin
                cnt <=  cnt - 3'd1;
                cnt <=  cnt - 4;
                addr_r[3:2] <=  addr_r[3:2] + 1'b1;
                addr_r[`OR1200_DCLS-1:2] <=  addr_r[`OR1200_DCLS-1:2] + 1;
             end
             end
             else if (biudata_valid & !(|cnt)) begin
             else if (biudata_valid & !(|cnt)) begin
                state <= `OR1200_DCFSM_LOOP3;
                state <= `OR1200_DCFSM_LOOP3;
                addr_r <=  lsu_addr;
                addr_r <=  lsu_addr;
                load <= 1'b0;
                load <= 1'b0;
Line 476... Line 477...
          `OR1200_DCFSM_LOOP3: begin // figure out next step
          `OR1200_DCFSM_LOOP3: begin // figure out next step
             if (cache_dirty_needs_writeback) begin
             if (cache_dirty_needs_writeback) begin
                // Just did store of the dirty line so now load new one
                // Just did store of the dirty line so now load new one
                load <= 1'b1;
                load <= 1'b1;
                // Set the counter for the burst accesses
                // Set the counter for the burst accesses
                cnt <=  `OR1200_DCLS-1;
                cnt <=  ((1 << `OR1200_DCLS) - 4);
                // Address of line to be loaded
                // Address of line to be loaded
                addr_r <=  lsu_addr;
                addr_r <=  lsu_addr;
                cache_dirty_needs_writeback <= 1'b0;
                cache_dirty_needs_writeback <= 1'b0;
                state <= `OR1200_DCFSM_LOOP2;
                state <= `OR1200_DCFSM_LOOP2;
             end // if (cache_dirty_needs_writeback)
             end // if (cache_dirty_needs_writeback)
Line 524... Line 525...
`ifdef OR1200_VERBOSE
`ifdef OR1200_VERBOSE
                     $display("%t: block flush: dirty block", $time);
                     $display("%t: block flush: dirty block", $time);
`endif
`endif
                     state <= `OR1200_DCFSM_LOOP2;
                     state <= `OR1200_DCFSM_LOOP2;
                     // Set the counter for the burst accesses
                     // Set the counter for the burst accesses
                     cnt <=  `OR1200_DCLS-1;
                     cnt <=  ((1 << `OR1200_DCLS) - 4);
                  end
                  end
                  else if (cache_spr_block_flush & !dirty)
                  else if (cache_spr_block_flush & !dirty)
                    begin
                    begin
                       // Line not dirty, just need to invalidate
                       // Line not dirty, just need to invalidate
                       state <=  `OR1200_DCFSM_INV6;
                       state <=  `OR1200_DCFSM_INV6;

powered by: WebSVN 2.1.0

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