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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber25/] [a25_icache.v] - Diff between revs 17 and 35

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

Rev 17 Rev 35
Line 88... Line 88...
input      [31:0]                   i_address,          // registered address from execute
input      [31:0]                   i_address,          // registered address from execute
input      [31:0]                   i_address_nxt,      // un-registered version of address from execute stage
input      [31:0]                   i_address_nxt,      // un-registered version of address from execute stage
input                               i_cache_enable,     // from co-processor 15 configuration register
input                               i_cache_enable,     // from co-processor 15 configuration register
input                               i_cache_flush,      // from co-processor 15 register
input                               i_cache_flush,      // from co-processor 15 register
 
 
output      [31:0]                  o_read_data,
output     [127:0]                  o_read_data,
 
 
// WB Read Request                                                          
// WB Read Request                                                          
output                              o_wb_req,          // Read Request
output                              o_wb_req,          // Read Request
input      [31:0]                   i_wb_read_data,
input      [127:0]                  i_wb_read_data,
input                               i_wb_ready
input                               i_wb_ready
);
);
 
 
`include "a25_localparams.v"
`include "a25_localparams.v"
`include "a25_functions.v"
`include "a25_functions.v"
Line 138... Line 138...
 
 
wire [CACHE_ADDR_WIDTH-1:0] tag_address;
wire [CACHE_ADDR_WIDTH-1:0] tag_address;
wire [TAG_WIDTH-1:0]        tag_wdata;
wire [TAG_WIDTH-1:0]        tag_wdata;
wire                        tag_wenable;
wire                        tag_wenable;
 
 
wire [CACHE_LINE_WIDTH-1:0] data_wdata;
 
wire [CACHE_ADDR_WIDTH-1:0] data_address;
wire [CACHE_ADDR_WIDTH-1:0] data_address;
wire [31:0]                 write_data_word;
wire [31:0]                 write_data_word;
 
 
wire                        idle_hit;
wire                        idle_hit;
wire                        read_miss;
wire                        read_miss;
Line 159... Line 158...
wire                        enable;
wire                        enable;
wire [CACHE_ADDR_WIDTH-1:0] address;
wire [CACHE_ADDR_WIDTH-1:0] address;
wire [31:0]                 address_c;
wire [31:0]                 address_c;
reg  [31:0]                 address_r = 'd0;
reg  [31:0]                 address_r = 'd0;
 
 
reg  [CACHE_LINE_WIDTH-1:0] wb_rdata_burst_r = 'd0;
 
wire [CACHE_LINE_WIDTH-1:0] wb_rdata_burst;
 
 
 
reg  [31:0]                 wb_address = 'd0;
reg  [31:0]                 wb_address = 'd0;
wire                        rbuf_hit = 'd0;
 
wire                        wb_hit;
wire                        wb_hit;
 
wire                        read_buf_hit;
 
reg  [127:0]                read_buf_data_r;
 
reg  [31:0]                 read_buf_addr_r;
 
reg                         read_buf_valid_r;
genvar                      i;
genvar                      i;
 
 
// ======================================
// ======================================
// Address to use for cache access
// Address to use for cache access
// ======================================
// ======================================
// If currently stalled then the address for the next
// If currently stalled then the address for the next
// cycle will be the same as it is in the current cycle
// cycle will be the same as it is in the current cycle
//
//
assign address_c = i_core_stall ? i_address    : //[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
assign address_c = i_core_stall ? i_address    :
                                i_address_nxt; //[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] ;
                                  i_address_nxt;
 
 
assign address   = address_c[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB];
assign address   = address_c[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB];
 
 
 
 
// ======================================
// ======================================
// Outputs
// Outputs
// ======================================
// ======================================
assign o_read_data      = wb_hit                                       ? i_wb_read_data     :
assign o_read_data      = wb_hit                                       ? i_wb_read_data     :
                          i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd0 ? hit_rdata [31:0]   :
                          read_buf_hit ? read_buf_data_r :
                          i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd1 ? hit_rdata [63:32]  :
                                         hit_rdata ;
                          i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd2 ? hit_rdata [95:64]  :
 
                                                                         hit_rdata [127:96] ;
 
 
 
// Don't allow the cache to stall the wb i/f for an exclusive access
// Don't allow the cache to stall the wb i/f for an exclusive access
// The cache needs a couple of cycles to flush a potential copy of the exclusive
// The cache needs a couple of cycles to flush a potential copy of the exclusive
// address, but the wb can do the access in parallel. So there is no
// address, but the wb can do the access in parallel. So there is no
// stall in the state CS_EX_DELETE, even though the cache is out of action. 
// stall in the state CS_EX_DELETE, even though the cache is out of action. 
Line 198... Line 197...
 
 
assign o_wb_req         = read_miss && c_state == CS_IDLE;
assign o_wb_req         = read_miss && c_state == CS_IDLE;
 
 
 
 
// ======================================
// ======================================
 
// Read Buffer
 
// ======================================
 
always@(posedge i_clk)
 
    if ( i_cache_flush )
 
        read_buf_valid_r <= 1'd0;
 
    else if (i_wb_ready && c_state == CS_FILL3)
 
        begin
 
        read_buf_data_r  <= i_wb_read_data;
 
        read_buf_addr_r  <= miss_address;
 
        read_buf_valid_r <= 1'd1;
 
        end
 
    else if (o_wb_req)
 
        read_buf_valid_r <= 1'd0;
 
 
 
 
 
assign read_buf_hit     = read_buf_valid_r && i_address[31:4] == read_buf_addr_r[31:4];
 
 
 
// ======================================
// Cache State Machine
// Cache State Machine
// ======================================
// ======================================
 
 
// Little State Machine to Flush Tag RAMS
// Little State Machine to Flush Tag RAMS
always @ ( posedge i_clk )
always @ ( posedge i_clk )
Line 232... Line 249...
             CS_IDLE :
             CS_IDLE :
                begin
                begin
                source_sel  <= 1'd1 << C_CORE;
                source_sel  <= 1'd1 << C_CORE;
 
 
                if ( read_miss )
                if ( read_miss )
                    c_state <= CS_FILL0;
 
               end
 
 
 
             CS_FILL0 :
 
                begin
 
                // wb read request asserted, wait for ack
 
                if ( i_wb_ready )
 
                    c_state <= CS_FILL1;
 
                end
 
 
 
             CS_FILL1 :
 
                begin
 
                // wb read request asserted, wait for ack
 
                if ( i_wb_ready )
 
                    c_state <= CS_FILL2;
 
                end
 
 
 
 
 
             CS_FILL2 :
 
                // first read of burst of 4
 
                // wb read request asserted, wait for ack
 
                if ( i_wb_ready )
 
                    c_state <= CS_FILL3;
                    c_state <= CS_FILL3;
 
               end
 
 
 
 
             CS_FILL3 :
             CS_FILL3 :
                begin
                begin
 
                // Pick a way to write the cache update into
 
                // Either pick one of the invalid caches, or if all are valid, then pick
 
                // one randomly
                select_way  <= next_way;
                select_way  <= next_way;
                random_num  <= {random_num[2], random_num[1], random_num[0],
                random_num  <= {random_num[2], random_num[1], random_num[0],
                                 random_num[3]^random_num[2]};
                                 random_num[3]^random_num[2]};
 
 
                // third read of burst of 4
                // third read of burst of 4
                // wb read request asserted, wait for ack
                // wb read request asserted, wait for ack
                if ( i_wb_ready )
                if ( i_wb_ready )
                    begin
                    begin
                    c_state     <= CS_FILL_COMPLETE;
                    c_state     <= CS_FILL_COMPLETE;
 
 
                    // Pick a way to write the cache update into
 
                    // Either pick one of the invalid caches, or if all are valid, then pick
 
                    // one randomly
 
 
 
                    end
                    end
                end
                end
 
 
 
 
             // Write the read fetch data in this cycle
             // Write the read fetch data in this cycle
Line 300... Line 294...
 
 
        endcase
        endcase
 
 
 
 
// ======================================
// ======================================
// Capture WB Block Read - burst of 4 words
 
// ======================================
 
assign wb_rdata_burst = {i_wb_read_data, wb_rdata_burst_r[127:32]};
 
always @ ( posedge i_clk )
 
    if ( i_wb_ready )
 
        wb_rdata_burst_r <= wb_rdata_burst;
 
 
 
 
 
// ======================================
 
// Miss Address
// Miss Address
// ======================================
// ======================================
always @ ( posedge i_clk )
always @ ( posedge i_clk )
    if ( c_state == CS_IDLE )
    if ( c_state == CS_IDLE )
        miss_address <= i_address;
        miss_address <= i_address;
Line 328... Line 313...
    if ( o_wb_req )
    if ( o_wb_req )
        wb_address <= i_address;
        wb_address <= i_address;
    else if ( i_wb_ready && fill_state )
    else if ( i_wb_ready && fill_state )
        wb_address <= {wb_address[31:4], wb_address[3:2] + 1'd1, 2'd0};
        wb_address <= {wb_address[31:4], wb_address[3:2] + 1'd1, 2'd0};
 
 
assign fill_state       = c_state == CS_FILL0 || c_state == CS_FILL1 || c_state == CS_FILL2 || c_state == CS_FILL3 ;
assign fill_state       = c_state == CS_FILL3;
assign wb_hit           = i_address == wb_address && i_wb_ready && fill_state;
assign wb_hit           = i_address == wb_address && i_wb_ready && fill_state;
 
 
assign tag_address      = read_miss_fill     ? miss_address      [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
assign tag_address      = read_miss_fill     ? miss_address      [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
                          source_sel[C_INIT] ? init_count[CACHE_ADDR_WIDTH-1:0]                      :
                          source_sel[C_INIT] ? init_count[CACHE_ADDR_WIDTH-1:0]                      :
                                               address                                               ;
                                               address                                               ;
Line 344... Line 329...
 
 
assign tag_wdata        = read_miss_fill     ? {1'd1, miss_address[31:TAG_ADDR32_LSB]} :
assign tag_wdata        = read_miss_fill     ? {1'd1, miss_address[31:TAG_ADDR32_LSB]} :
                                               {TAG_WIDTH{1'd0}}                       ;
                                               {TAG_WIDTH{1'd0}}                       ;
 
 
 
 
// Data comes in off the WB bus in wrap4 with the missed data word first
 
assign data_wdata       = miss_address[3:2] == 2'd0 ? { wb_rdata_burst[127:0]                        }:
 
                          miss_address[3:2] == 2'd1 ? { wb_rdata_burst[95:0], wb_rdata_burst[127:96] }:
 
                          miss_address[3:2] == 2'd2 ? { wb_rdata_burst[63:0], wb_rdata_burst[127:64] }:
 
                                                      { wb_rdata_burst[31:0], wb_rdata_burst[127:32] };
 
 
 
 
 
assign read_miss_fill   = c_state == CS_FILL3 && i_wb_ready;
assign read_miss_fill   = c_state == CS_FILL3 && i_wb_ready;
 
 
 
 
 
 
assign tag_wenable      = read_miss_fill     ? 1'd1  :
assign tag_wenable      = read_miss_fill     ? 1'd1  :
Line 369... Line 347...
 
 
assign idle_hit         = |data_hit_way;
assign idle_hit         = |data_hit_way;
 
 
assign read_miss        = enable && !idle_hit && !invalid_read;
assign read_miss        = enable && !idle_hit && !invalid_read;
 
 
assign read_stall       = enable && !idle_hit && !rbuf_hit && !wb_hit;
assign read_stall       = enable && !idle_hit && !wb_hit && !read_buf_hit;
 
 
assign cache_busy_stall = (c_state == CS_TURN_AROUND  && enable) || c_state == CS_INIT;
assign cache_busy_stall = (c_state == CS_TURN_AROUND  && enable && !read_buf_hit) || c_state == CS_INIT;
 
 
 
 
// ======================================
// ======================================
// Instantiate RAMS
// Instantiate RAMS
// ======================================
// ======================================
Line 425... Line 403...
            #(
            #(
            .DATA_WIDTH    ( CACHE_LINE_WIDTH) ,
            .DATA_WIDTH    ( CACHE_LINE_WIDTH) ,
            .ADDRESS_WIDTH ( CACHE_ADDR_WIDTH) )
            .ADDRESS_WIDTH ( CACHE_ADDR_WIDTH) )
        u_data (
        u_data (
            .i_clk                      ( i_clk                         ),
            .i_clk                      ( i_clk                         ),
            .i_write_data               ( data_wdata                    ),
            .i_write_data               ( i_wb_read_data                ),
            .i_write_enable             ( data_wenable_way[i]           ),
            .i_write_enable             ( data_wenable_way[i]           ),
            .i_address                  ( data_address                  ),
            .i_address                  ( data_address                  ),
            .i_byte_enable              ( {CACHE_LINE_WIDTH/8{1'd1}}    ),
            .i_byte_enable              ( {CACHE_LINE_WIDTH/8{1'd1}}    ),
            .o_read_data                ( data_rdata_way[i]             )
            .o_read_data                ( data_rdata_way[i]             )
            );
            );

powered by: WebSVN 2.1.0

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