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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [core/] [dcache.v] - Diff between revs 201 and 209

Show entire file | Details | Blame | View Log

Rev 201 Rev 209
Line 46... Line 46...
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2016, Gisselquist Technology, LLC
// Copyright (C) 2016-2019, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
Line 65... Line 65...
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
module  dcache(i_clk, i_rst, i_pipe_stb, i_lock,
`default_nettype        none
 
//
 
//
 
`ifdef  FORMAL
 
`define ASSERT  assert
 
 
 
`ifdef DCACHE
 
`define ASSUME  assume
 
`else
 
`define ASSUME  assert
 
`endif
 
`endif
 
 
 
module  dcache(i_clk, i_reset, i_pipe_stb, i_lock,
                i_op, i_addr, i_data, i_oreg,
                i_op, i_addr, i_data, i_oreg,
                        o_busy, o_pipe_stalled, o_valid, o_err, o_wreg,o_data,
                        o_busy, o_pipe_stalled, o_valid, o_err, o_wreg,o_data,
                o_wb_cyc_gbl, o_wb_cyc_lcl, o_wb_stb_gbl, o_wb_stb_lcl,
                o_wb_cyc_gbl, o_wb_cyc_lcl, o_wb_stb_gbl, o_wb_stb_lcl,
                        o_wb_we, o_wb_addr, o_wb_data,
                        o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
                i_wb_ack, i_wb_stall, i_wb_err, i_wb_data);
                i_wb_ack, i_wb_stall, i_wb_err, i_wb_data
 
`ifdef  FORMAL
 
                , f_nreqs, f_nacks, f_outstanding, f_pc
 
`endif
 
        );
        parameter       LGCACHELEN = 8,
        parameter       LGCACHELEN = 8,
                        ADDRESS_WIDTH=32,
                        ADDRESS_WIDTH=30,
                        LGNLINES=5, // Log of the number of separate cache lines
                        LGNLINES=(LGCACHELEN-3), // Log of the number of separate cache lines
                        IMPLEMENT_LOCK=0,
 
                        NAUX=5; // # of aux d-wires to keep aligned w/memops
                        NAUX=5; // # of aux d-wires to keep aligned w/memops
        localparam      SDRAM_BIT = 26;
        parameter [0:0]   OPT_LOCAL_BUS=1'b1;
        localparam      FLASH_BIT = 22;
        parameter [0:0]   OPT_PIPE=1'b1;
        localparam      BLKRAM_BIT= 15;
        parameter [0:0]   OPT_LOCK=1'b1;
 
        parameter [0:0]   OPT_DUAL_READ_PORT=1'b1;
 
        parameter       OPT_FIFO_DEPTH = 4;
        localparam      AW = ADDRESS_WIDTH; // Just for ease of notation below
        localparam      AW = ADDRESS_WIDTH; // Just for ease of notation below
        localparam      CS = LGCACHELEN; // Number of bits in a cache address
        localparam      CS = LGCACHELEN; // Number of bits in a cache address
        localparam      LS = CS-LGNLINES; // Bits to spec position w/in cline
        localparam      LS = CS-LGNLINES; // Bits to spec position w/in cline
 
        parameter       F_LGDEPTH=1 + (((!OPT_PIPE)||(LS > OPT_FIFO_DEPTH))
 
                                        ? LS : OPT_FIFO_DEPTH);
        localparam      LGAUX = 3; // log_2 of the maximum number of piped data 
        localparam      LGAUX = 3; // log_2 of the maximum number of piped data 
        input                   i_clk, i_rst;
        localparam      DW = 32; // Bus data width
 
        localparam      DP = OPT_FIFO_DEPTH;
 
        //
 
        localparam [1:0] DC_IDLE  = 2'b00; // Bus is idle
 
        localparam [1:0] DC_WRITE = 2'b01; // Write
 
        localparam [1:0] DC_READS = 2'b10; // Read a single value(!cachd)
 
        localparam [1:0] DC_READC = 2'b11; // Read a whole cache line
 
        //
 
        input   wire            i_clk, i_reset;
        // Interface from the CPU
        // Interface from the CPU
        input                   i_pipe_stb, i_lock;
        input   wire            i_pipe_stb, i_lock;
        input                   i_op;
        input   wire [2:0]               i_op;
        input   [31:0]           i_addr;
        input   wire [(DW-1):0]  i_addr;
        input   [31:0]           i_data;
        input   wire [(DW-1):0]  i_data;
        input   [(NAUX-1):0]     i_oreg; // Aux data, such as reg to write to
        input   wire [(NAUX-1):0] i_oreg; // Aux data, such as reg to write to
        // Outputs, going back to the CPU
        // Outputs, going back to the CPU
        output  wire            o_busy, o_pipe_stalled, o_valid, o_err;
        output  reg             o_busy;
 
        output  reg             o_pipe_stalled;
 
        output  reg             o_valid, o_err;
        output reg [(NAUX-1):0]  o_wreg;
        output reg [(NAUX-1):0]  o_wreg;
        output  reg     [31:0]   o_data;
        output  reg [(DW-1):0]   o_data;
        // Wishbone bus master outputs
        // Wishbone bus master outputs
        output  wire            o_wb_cyc_gbl, o_wb_cyc_lcl;
        output  wire            o_wb_cyc_gbl, o_wb_cyc_lcl;
        output  reg             o_wb_stb_gbl, o_wb_stb_lcl;
        output  reg             o_wb_stb_gbl, o_wb_stb_lcl;
        output  reg             o_wb_we;
        output  reg             o_wb_we;
        output  reg     [(AW-1):0]       o_wb_addr;
        output  reg     [(AW-1):0]       o_wb_addr;
        output  reg     [31:0]           o_wb_data;
        output  reg [(DW-1):0]   o_wb_data;
 
        output  wire [(DW/8-1):0] o_wb_sel;
        // Wishbone bus slave response inputs
        // Wishbone bus slave response inputs
        input                           i_wb_ack, i_wb_stall, i_wb_err;
        input   wire                    i_wb_ack, i_wb_stall, i_wb_err;
        input           [31:0]           i_wb_data;
        input   wire    [(DW-1):0]       i_wb_data;
 
`ifdef FORMAL
 
        output  wire [(F_LGDEPTH-1):0]   f_nreqs, f_nacks, f_outstanding;
 
        output  wire                    f_pc;
 
 
 
        reg     f_past_valid;
 
`endif
 
        //
 
        // output       reg     [31:0]          o_debug;
 
 
 
 
        reg     cyc, stb, last_ack, end_of_line, last_line_stb;
        reg     cyc, stb, last_ack, end_of_line, last_line_stb;
 
        reg     r_wb_cyc_gbl, r_wb_cyc_lcl;
 
        // npending is the number of pending non-cached operations, counted
 
        // from the i_pipe_stb to the o_wb_ack
 
        reg     [DP:0]   npending;
 
 
 
 
        reg     [((1<<LGNLINES)-1):0] c_v;       // One bit per cache line, is it valid?
        reg     [((1<<LGNLINES)-1):0] c_v;       // One bit per cache line, is it valid?
        reg     [(AW-LS-1):0]    c_vtags [0:((1<<LGNLINES)-1)];
        reg     [(AW-LS-1):0]    c_vtags [0:((1<<LGNLINES)-1)];
        reg     [31:0]           c_mem   [0:((1<<CS)-1)];
        reg     [(DW-1):0]       c_mem   [0:((1<<CS)-1)];
        // reg  [((1<<LGNLINES)-1):0]   c_wr; // Is the cache line writable?
        reg                     set_vflag;
        // reg  c_wdata;
        reg     [1:0]            state;
        // reg  c_waddr;
        reg     [(CS-1):0]       wr_addr;
 
        reg     [(DW-1):0]       cached_idata, cached_rdata;
 
        reg     [DW-1:0] pre_data;
 
        reg                     lock_gbl, lock_lcl;
 
 
 
 
        // To simplify writing to the cache, and the job of the synthesizer to
        // To simplify writing to the cache, and the job of the synthesizer to
        // recognize that a cache write needs to take place, we'll take an extra
        // recognize that a cache write needs to take place, we'll take an extra
        // clock to get there, and use these c_w... registers to capture the
        // clock to get there, and use these c_w... registers to capture the
        // data in the meantime.
        // data in the meantime.
        reg                     c_wr;
        reg                     c_wr;
        reg     [31:0]           c_wdata;
        reg     [(DW-1):0]       c_wdata;
 
        reg     [(DW/8-1):0]     c_wsel;
        reg     [(CS-1):0]       c_waddr;
        reg     [(CS-1):0]       c_waddr;
 
 
        reg     [(AW-LS-1):0]    last_tag;
        reg     [(AW-LS-1):0]    last_tag;
 
        reg                     last_tag_valid;
 
 
 
 
        wire    [(LGNLINES-1):0] i_cline;
        wire    [(LGNLINES-1):0] i_cline;
        wire    [(CS-1):0]       i_caddr;
        wire    [(CS-1):0]       i_caddr;
        wire    [(AW-LS-1):0]    i_ctag;
 
 
 
        assign  i_cline = i_addr[(CS-1):LS];
`ifdef  FORMAL
        assign  i_caddr = i_addr[(CS-1):0];
        reg     [F_LGDEPTH-1:0]  f_fill;
        assign  i_ctag  = i_addr[(AW-1):LS];
        reg     [AW:0]           f_return_address;
 
        reg     [AW:0]           f_pending_addr;
 
`endif
 
 
 
        assign  i_cline = i_addr[(CS+1):LS+2];
 
        assign  i_caddr = i_addr[(CS+1):2];
 
 
        wire    cache_miss_inow, w_cachable;
        wire    cache_miss_inow, w_cachable;
        assign  cache_miss_inow = (last_tag != i_addr[31:LS])||(!c_v[i_cline]);
        assign  cache_miss_inow = (!last_tag_valid)
        assign  w_cachable = (i_addr[31:30]!=2'b11)&&(!i_lock)&&(
                                        ||(last_tag != i_addr[(AW+1):LS+2])
                                ((SDRAM_BIT>0)&&(i_addr[SDRAM_BIT]))
                                        ||(!c_v[i_cline]);
                                ||((FLASH_BIT>0)&&(i_addr[FLASH_BIT]))
 
                                ||((BLKRAM_BIT>0)&&(i_addr[BLKRAM_BIT])));
 
 
 
        reg     r_cachable, r_svalid, r_dvalid, r_rd, r_cache_miss, r_rvalid;
        wire    raw_cachable_address;
 
 
 
        iscachable chkaddress(i_addr[AW+1:2], raw_cachable_address);
 
 
 
        assign  w_cachable = ((!OPT_LOCAL_BUS)||(i_addr[(DW-1):(DW-8)]!=8'hff))
 
                &&((!i_lock)||(!OPT_LOCK))&&(raw_cachable_address);
 
 
 
        reg     r_cachable, r_svalid, r_dvalid, r_rd, r_cache_miss,
 
                r_rd_pending;
        reg     [(AW-1):0]       r_addr;
        reg     [(AW-1):0]       r_addr;
        reg     [31:0]           r_idata, r_ddata, r_rdata;
 
        wire    [(LGNLINES-1):0] r_cline;
        wire    [(LGNLINES-1):0] r_cline;
        wire    [(CS-1):0]       r_caddr;
        wire    [(CS-1):0]       r_caddr;
        wire    [(AW-LS-1):0]    r_ctag;
        wire    [(AW-LS-1):0]    r_ctag;
 
 
        assign  r_cline = r_addr[(CS-1):LS];
        assign  r_cline = r_addr[(CS-1):LS];
        assign  r_caddr = r_addr[(CS-1):0];
        assign  r_caddr = r_addr[(CS-1):0];
        assign  r_ctag  = r_addr[(AW-1):LS];
        assign  r_ctag  = r_addr[(AW-1):LS];
 
 
 
 
        reg     wr_cstb, r_iv, pipeable_op, non_pipeable_op, in_cache;
        reg     wr_cstb, r_iv, in_cache;
        reg     [(AW-LS-1):0]    r_itag;
        reg     [(AW-LS-1):0]    r_itag;
 
        reg     [DW/8-1:0]       r_sel;
 
        reg     [(NAUX+4-1):0]   req_data;
 
        reg                     gie;
 
 
 
 
 
 
        //
        //
        // The one-clock delayed read values from the cache.
        // The one-clock delayed read values from the cache.
        //
        //
        initial r_rd = 1'b0;
        initial r_rd = 1'b0;
        initial r_cachable = 1'b0;
        initial r_cachable = 1'b0;
        initial r_svalid = 1'b0;
        initial r_svalid = 1'b0;
        initial r_dvalid = 1'b0;
        initial r_dvalid = 1'b0;
 
        initial r_cache_miss = 1'b0;
 
        initial r_addr = 0;
 
        initial last_tag_valid = 0;
 
        initial r_rd_pending = 0;
        always @(posedge i_clk)
        always @(posedge i_clk)
 
        if (i_reset)
        begin
        begin
 
                r_rd <= 1'b0;
 
                r_cachable <= 1'b0;
 
                r_svalid <= 1'b0;
 
                r_dvalid <= 1'b0;
 
                r_cache_miss <= 1'b0;
 
                r_addr <= 0;
 
                r_rd_pending <= 0;
 
                last_tag_valid <= 0;
 
        end else begin
                // The single clock path
                // The single clock path
                r_idata <= c_mem[i_addr[(CS-1):0]];
 
                // The valid for the single clock path
                // The valid for the single clock path
                //      Only ... we need to wait if we are currently writing
                //      Only ... we need to wait if we are currently writing
                //      to our cache.
                //      to our cache.
                r_svalid<= (!i_op)&&(!cache_miss_inow)&&(w_cachable)
                r_svalid<= (i_pipe_stb)&&(!i_op[0])&&(w_cachable)
                                &&(i_pipe_stb)&&(!c_wr)&&(!wr_cstb);
                                &&(!cache_miss_inow)&&(!c_wr)&&(!wr_cstb);
 
 
                //
                //
                // The two clock in-cache path
                // The two clock in-cache path
                //
                //
                // Some preliminaries that needed to be calculated on the first
                // Some preliminaries that needed to be calculated on the first
                // clock
                // clock
                if (!o_busy)
                if ((!o_pipe_stalled)&&(!r_rd_pending))
 
                        r_addr <= i_addr[(AW+1):2];
 
                if ((!o_pipe_stalled)&&(!r_rd_pending))
                begin
                begin
                        r_iv   <= c_v[i_cline];
                        r_iv   <= c_v[i_cline];
                        r_itag <= c_vtags[i_cline];
                        r_itag <= c_vtags[i_cline];
                        r_addr <= i_addr;
                        r_cachable <= (!i_op[0])&&(w_cachable)&&(i_pipe_stb);
                        r_cachable <= (!i_op)&&(w_cachable)&&(i_pipe_stb);
                        r_rd_pending <= (i_pipe_stb)&&(!i_op[0])&&(w_cachable)
 
                                &&((cache_miss_inow)||(c_wr)||(wr_cstb));
 
                                // &&((!c_wr)||(!wr_cstb));
                end else begin
                end else begin
                        r_iv   <= c_v[r_cline];
                        r_iv   <= c_v[r_cline];
                        r_itag <= c_vtags[r_cline];
                        r_itag <= c_vtags[r_cline];
 
                        r_rd_pending <= (r_rd_pending)
 
                                &&((!cyc)||(!i_wb_err))
 
                                &&((r_itag != r_ctag)||(!r_iv));
                end
                end
                // r_idata still contains the right answer
                r_rd <= (i_pipe_stb)&&(!i_op[0]);
                r_rd <= (i_pipe_stb)&&(!i_op);
 
                r_ddata  <= r_idata;
 
                // r_itag contains the tag we didn't have available to us on the
                // r_itag contains the tag we didn't have available to us on the
                // last clock, r_ctag is a bit select from r_addr containing a
                // last clock, r_ctag is a bit select from r_addr containing a
                // one clock delayed address.
                // one clock delayed address.
                r_dvalid <= (r_itag == r_ctag)&&(r_iv)&&(r_cachable);
                r_dvalid <= (!r_svalid)&&(!r_dvalid)&&(r_itag == r_ctag)&&(r_iv)
                if ((r_itag == r_ctag)&&(r_iv)&&(r_cachable))
                                                &&(r_cachable)&&(r_rd_pending);
 
                if ((r_itag == r_ctag)&&(r_iv)&&(r_cachable)&&(r_rd_pending))
 
                begin
 
                        last_tag_valid <= 1'b1;
                        last_tag <= r_ctag;
                        last_tag <= r_ctag;
 
                end else if ((state == DC_READC)
 
                                &&(last_tag[CS-LS-1:0]==o_wb_addr[CS-1:LS])
 
                                &&((i_wb_ack)||(i_wb_err)))
 
                        last_tag_valid <= 1'b0;
 
 
                // r_cache miss takes a clock cycle.  It is only ever true for
                // r_cache miss takes a clock cycle.  It is only ever true for
                // something that should be cachable, but isn't in the cache.
                // something that should be cachable, but isn't in the cache.
                // A cache miss is only true _if_
                // A cache miss is only true _if_
                // 1. A read was requested
                // 1. A read was requested
Line 212... Line 300...
                                // One clock path -- miss
                                // One clock path -- miss
                                &&(!r_svalid)
                                &&(!r_svalid)
                                // Two clock path -- misses as well
                                // Two clock path -- misses as well
                                &&(r_rd)&&(!r_svalid)
                                &&(r_rd)&&(!r_svalid)
                                &&((r_itag != r_ctag)||(!r_iv));
                                &&((r_itag != r_ctag)||(!r_iv));
 
        end
 
 
                r_rdata <= c_mem[r_addr[(CS-1):0]];
        initial r_sel = 4'hf;
                r_rvalid<= ((i_wb_ack)&&(last_ack));
        always @(posedge i_clk)
 
        if (i_reset)
 
                r_sel <= 4'hf;
 
        else if (!o_pipe_stalled)
 
        begin
 
                casez({i_op[2:1], i_addr[1:0]})
 
                4'b0???: r_sel <= 4'b1111;
 
                4'b100?: r_sel <= 4'b1100;
 
                4'b101?: r_sel <= 4'b0011;
 
                4'b1100: r_sel <= 4'b1000;
 
                4'b1101: r_sel <= 4'b0100;
 
                4'b1110: r_sel <= 4'b0010;
 
                4'b1111: r_sel <= 4'b0001;
 
                endcase
        end
        end
 
 
`define DC_IDLE         2'b00
        assign  o_wb_sel = (state == DC_READC) ? 4'hf : r_sel;
`define DC_WRITE        2'b01
 
`define DC_READS        2'b10
 
`define DC_READC        2'b11
 
        reg     [1:0]    state;
 
 
 
        reg     [(AW-LS-1):0]    wr_wtag, wr_vtag;
        initial o_wb_data = 0;
        reg     [31:0]           wr_data;
        always @(posedge i_clk)
        reg     [(CS-1):0]       wr_addr;
        if (i_reset)
 
                o_wb_data <= 0;
 
        else if ((!o_busy)||((stb)&&(!i_wb_stall)))
 
        begin
 
                casez(i_op[2:1])
 
                2'b0?: o_wb_data <= i_data;
 
                2'b10: o_wb_data <= { (2){i_data[15:0]} };
 
                2'b11: o_wb_data <= { (4){i_data[ 7:0]} };
 
                endcase
 
        end
 
 
 
        generate if (OPT_PIPE)
 
        begin : OPT_PIPE_FIFO
 
                reg     [NAUX+4-2:0]     fifo_data [0:((1<<OPT_FIFO_DEPTH)-1)];
 
 
 
                reg     [DP:0]           wraddr, rdaddr;
 
 
 
                always @(posedge i_clk)
 
                if (i_pipe_stb)
 
                        fifo_data[wraddr[DP-1:0]]
 
                                <= { i_oreg[NAUX-2:0], i_op[2:1], i_addr[1:0] };
 
 
 
                always @(posedge i_clk)
 
                if (i_pipe_stb)
 
                        gie <= i_oreg[NAUX-1];
 
 
 
`ifdef  NO_BKRAM
 
                reg     [NAUX+4-2:0]     r_req_data, r_last_data;
 
                reg                     single_write;
 
 
 
                always @(posedge i_clk)
 
                        r_req_data <= fifo_data[rdaddr[DP-1:0]];
 
 
 
                always @(posedge i_clk)
 
                        single_write <= (rdaddr == wraddr)&&(i_pipe_stb);
 
 
 
                always @(posedge i_clk)
 
                if (i_pipe_stb)
 
                        r_last_data <= { i_oreg[NAUX-2:0],
 
                                                i_op[2:1], i_addr[1:0] };
 
 
 
                always @(*)
 
                begin
 
                        req_data[NAUX+4-1] = gie;
 
                        // if ((r_svalid)||(state == DC_READ))
 
                        if (single_write)
 
                                req_data[NAUX+4-2:0] = r_last_data;
 
                        else
 
                                req_data[NAUX+4-2:0] = r_req_data;
 
                end
 
 
 
                always @(*)
 
                        `ASSERT(req_data == fifo_data[rdaddr[DP-1:0]]);
 
`else
 
                always @(*)
 
                        req_data[NAUX+4-2:0] = fifo_data[rdaddr[DP-1:0]];
 
                always @(*)
 
                        req_data[NAUX+4-1] = gie;
 
`endif
 
 
 
                initial wraddr = 0;
 
                always @(posedge i_clk)
 
                if ((i_reset)||((cyc)&&(i_wb_err)))
 
                        wraddr <= 0;
 
                else if (i_pipe_stb)
 
                        wraddr <= wraddr + 1'b1;
 
 
 
                initial rdaddr = 0;
 
                always @(posedge i_clk)
 
                if ((i_reset)||((cyc)&&(i_wb_err)))
 
                        rdaddr <= 0;
 
                else if ((r_dvalid)||(r_svalid))
 
                        rdaddr <= rdaddr + 1'b1;
 
                else if ((state == DC_WRITE)&&(i_wb_ack))
 
                        rdaddr <= rdaddr + 1'b1;
 
                else if ((state == DC_READS)&&(i_wb_ack))
 
                        rdaddr <= rdaddr + 1'b1;
 
 
 
`ifdef  FORMAL
 
                reg     [AW-1:0] f_fifo_addr [0:((1<<OPT_FIFO_DEPTH)-1)];
 
                reg     [F_LGDEPTH-1:0]  f_last_wraddr;
 
                reg     f_pc_pending;
 
 
 
                always @(*)
 
                begin
 
                        f_fill = 0;
 
                        f_fill[DP:0] = wraddr - rdaddr;
 
                end
 
 
 
                always @(*)
 
                        `ASSERT(f_fill <= { 1'b1, {(DP){1'b0}} });
 
 
 
                always @(*)
 
                if ((r_dvalid)||(r_svalid))
 
                begin
 
                        if (r_svalid)
 
                                `ASSERT(f_fill == 1);
 
                        else if (r_dvalid)
 
                                `ASSERT(f_fill == 1);
 
                        else
 
                                `ASSERT(f_fill == 0);
 
                end else if (r_rd_pending)
 
                        `ASSERT(f_fill == 1);
 
                else
 
                        `ASSERT(f_fill == npending);
 
 
 
 
 
                initial f_pc_pending = 0;
 
                always @(posedge i_clk)
 
                if (i_reset)
 
                        f_pc_pending <= 1'b0;
 
                else if (i_pipe_stb)
 
                        f_pc_pending <= (!i_op[0])&&(i_oreg[3:1] == 3'h7);
 
                else if (f_fill == 0)
 
                        f_pc_pending <= 1'b0;
 
                //else if ((o_valid)&&(o_wreg[3:1] == 3'h7)&&(f_fill == 0))
 
                //      f_pc_pending <= 1'b0;
 
 
 
                always @(posedge i_clk)
 
                if (f_pc_pending)
 
                        `ASSUME(!i_pipe_stb);
 
 
 
                always @(posedge i_clk)
 
                if (state == DC_WRITE)
 
                        `ASSERT(!f_pc_pending);
 
 
 
                always @(*)
 
                begin
 
                        f_last_wraddr = 0;
 
                        f_last_wraddr[DP:0] = wraddr - 1'b1;
 
                end
 
 
 
                always @(posedge i_clk)
 
                if (r_rd_pending)
 
                        `ASSERT(f_pc_pending == (fifo_data[f_last_wraddr][7:5] == 3'h7));
 
 
 
`define INSPECT_FIFO
 
                reg     [((1<<(DP+1))-1):0]      f_valid_fifo_entry;
 
 
 
                genvar  k;
 
                for(k=0; k<(1<<(DP+1)); k=k+1)
 
                begin
 
 
 
                        always @(*)
 
                        begin
 
                        f_valid_fifo_entry[k] = 1'b0;
 
                        /*
 
                        if ((rdaddr[DP] != wraddr[DP])
 
                                        &&(rdaddr[DP-1:0] == wraddr[DP-1:0]))
 
                                f_valid_fifo_entry[k] = 1'b1;
 
                        else */
 
                        if ((rdaddr < wraddr)&&(k < wraddr)
 
                                        &&(k >= rdaddr))
 
                                f_valid_fifo_entry[k] = 1'b1;
 
                        else if ((rdaddr > wraddr)&&(k >= rdaddr))
 
                                f_valid_fifo_entry[k] = 1'b1;
 
                        else if ((rdaddr > wraddr)&&(k <  wraddr))
 
                                f_valid_fifo_entry[k] = 1'b1;
 
                        end
 
 
 
`ifdef  INSPECT_FIFO
 
                        wire    [NAUX+4-2:0]     fifo_data_k;
 
 
 
                        assign  fifo_data_k = fifo_data[k[DP-1:0]];
 
                        always @(*)
 
                        if (f_valid_fifo_entry[k])
 
                        begin
 
                                if (!f_pc_pending)
 
                                        `ASSERT((o_wb_we)||(fifo_data_k[7:5] != 3'h7));
 
                                else if (k != f_last_wraddr)
 
                                        `ASSERT(fifo_data_k[7:5] != 3'h7);
 
                        end
 
`endif // INSPECT_FIFO
 
 
 
                end
 
 
 
`ifndef INSPECT_FIFO
 
                always @(posedge i_clk)
 
                if ((r_rd_pending)&&(rdaddr[DP:0] != f_last_wraddr[DP-1]))
 
                        assume(fifo_data[rdaddr][7:5] != 3'h7);
 
`endif // INSPECT_FIFO
 
 
 
                assign  f_pc = f_pc_pending;
 
 
 
                //
 
                //
 
                //
 
                always @(*)
 
                        f_pending_addr = f_fifo_addr[rdaddr];
 
 
 
                //
 
                //
 
                //
 
                always @(posedge i_clk)
 
                if (i_pipe_stb)
 
                        f_fifo_addr[wraddr[DP-1:0]] <= i_addr[AW+1:2];
 
 
 
                always @(*)
 
                begin
 
                        f_return_address[AW] = (o_wb_cyc_lcl);
 
                        f_return_address[AW-1:0] = f_fifo_addr[rdaddr];
 
                        if (state == DC_READC)
 
                                f_return_address[LS-1:0]
 
                                = (o_wb_addr[LS-1:0] - f_outstanding[LS-1:0]);
 
                end
 
 
 
`define TWIN_WRITE_TEST
 
`ifdef  TWIN_WRITE_TEST
 
                (* anyconst *)  reg     [DP:0]           f_twin_base;
 
                                reg     [DP:0]           f_twin_next;
 
                (* anyconst *)  reg     [AW+NAUX+4-2-1:0]        f_twin_first,
 
                                                        f_twin_second;
 
                // reg  [AW-1:0]        f_fifo_addr [0:((1<<OPT_FIFO_DEPTH)-1)];
 
                // reg  [NAUX+4-2:0]    fifo_data [0:((1<<OPT_FIFO_DEPTH)-1)];
 
 
 
                always @(*)     f_twin_next = f_twin_base+1;
 
 
 
                reg     f_twin_none, f_twin_single, f_twin_double, f_twin_last;
 
                reg     f_twin_valid_one, f_twin_valid_two;
 
                always @(*)
 
                begin
 
                        f_twin_valid_one = ((f_valid_fifo_entry[f_twin_base])
 
                                &&(f_twin_first == { f_fifo_addr[f_twin_base],
 
                                                fifo_data[f_twin_base] }));
 
                        f_twin_valid_two = ((f_valid_fifo_entry[f_twin_next])
 
                                &&(f_twin_second == { f_fifo_addr[f_twin_next],
 
                                                fifo_data[f_twin_next] }));
 
                end
 
 
 
                always @(*)
 
                begin
 
                        f_twin_none   =(!f_twin_valid_one)&&(!f_twin_valid_two);
 
                        f_twin_single =( f_twin_valid_one)&&(!f_twin_valid_two);
 
                        f_twin_double =( f_twin_valid_one)&&( f_twin_valid_two);
 
                        f_twin_last   =(!f_twin_valid_one)&&( f_twin_valid_two);
 
                end
 
 
 
                always @(posedge i_clk)
 
                if ((!f_past_valid)||($past(i_reset))||($past(cyc && i_wb_err)))
 
                        `ASSERT(f_twin_none);
 
                else if ($past(f_twin_none))
 
                        `ASSERT(f_twin_none || f_twin_single || f_twin_last);
 
                else if ($past(f_twin_single))
 
                        `ASSERT(f_twin_none || f_twin_single || f_twin_double || f_twin_last);
 
                else if ($past(f_twin_double))
 
                        `ASSERT(f_twin_double || f_twin_last);
 
                else if ($past(f_twin_last))
 
                        `ASSERT(f_twin_none || f_twin_single || f_twin_last);
 
 
 
`endif // TWIN_WRITE_TEST
 
 
 
                always @(*)
 
                        `ASSERT(req_data == { gie, fifo_data[rdaddr[DP-1:0]] });
 
 
 
                always @(posedge i_clk)
 
                if (r_svalid||r_dvalid || r_rd_pending)
 
                        `ASSERT(f_fill == 1);
 
                else if (f_fill > 0)
 
                        `ASSERT(cyc);
 
 
 
                always @(posedge i_clk)
 
                if (state != 0)
 
                        `ASSERT(f_fill > 0);
 
                else if (!r_svalid && !r_dvalid && !r_rd_pending)
 
                        `ASSERT(f_fill == 0);
 
 
 
`endif // FORMAL
 
 
 
                always @(posedge i_clk)
 
                        o_wreg <= req_data[(NAUX+4-1):4];
 
 
 
                /*
 
                reg     fifo_err;
 
                always @(posedge i_clk)
 
                begin
 
                        fifo_err <= 1'b0;
 
                        if ((!o_busy)&&(rdaddr != wraddr))
 
                                fifo_err <= 1'b1;
 
                        if ((!r_dvalid)&&(!r_svalid)&&(!r_rd_pending))
 
                                fifo_err <= (npending != (wraddr-rdaddr));
 
                end
 
 
 
                always @(*)
 
                o_debug = { i_pipe_stb, state, cyc, stb,        //  5b
 
                                fifo_err, i_oreg[3:0], o_wreg,          // 10b
 
                                rdaddr, wraddr,                 // 10b
 
                                i_wb_ack, i_wb_err, o_pipe_stalled, o_busy,//4b
 
                                r_svalid, r_dvalid, r_rd_pending };
 
                */
 
        end else begin : NO_FIFO
 
 
 
                always @(posedge i_clk)
 
                if (i_pipe_stb)
 
                        req_data <= { i_oreg, i_op[2:1], i_addr[1:0] };
 
 
 
                always @(*)
 
                        o_wreg = req_data[(NAUX+4-1):4];
 
 
 
                always @(*)
 
                        gie = i_oreg[NAUX-1];
 
 
 
`ifdef  FORMAL
 
                assign  f_pc = ((r_rd_pending)||(o_valid))&&(o_wreg[3:1] == 3'h7);
 
 
 
                //
 
                //
 
                //
 
                initial f_pending_addr = 0;
 
                always @(posedge i_clk)
 
                if (i_reset)
 
                        f_pending_addr <= 0;
 
                else if (i_pipe_stb)
 
                begin
 
                        f_pending_addr <= { (OPT_LOCAL_BUS)&&(&i_addr[DW-1:DW-8]),
 
                                                i_addr[(AW+1):2] };
 
                end
 
 
 
                //
 
                //
 
                always @(*)
 
                begin
 
                        f_return_address[AW]      = o_wb_cyc_lcl;
 
                        f_return_address[AW-1:LS] = o_wb_addr[AW-1:LS];
 
                end
 
                always @(*)
 
                if (state == DC_READS)
 
                        f_return_address[LS-1:0] = o_wb_addr[LS-1:0];
 
                else
 
                        f_return_address[LS-1:0]
 
                                = (o_wb_addr[LS-1:0] - f_outstanding[LS-1:0]);
 
 
 
`endif
 
                /*
 
                always @(*)
 
                o_debug = { i_pipe_stb, state, cyc, stb,        //  5b
 
                                i_oreg, o_wreg,                 // 10b
 
                                10'hb,                          // 10b
 
                                i_wb_ack, i_wb_err, o_pipe_stalled, o_busy,//4b
 
                                r_svalid, r_dvalid, r_rd_pending };
 
                */
 
 
 
                // verilator lint_off UNUSED
 
                wire    unused_no_fifo;
 
                assign  unused_no_fifo = gie;
 
                // verilator lint_on  UNUSED
 
        end endgenerate
 
 
 
 
 
        initial r_wb_cyc_gbl = 0;
 
        initial r_wb_cyc_lcl = 0;
 
        initial o_wb_stb_gbl = 0;
 
        initial o_wb_stb_lcl = 0;
 
        initial c_v = 0;
 
        initial cyc = 0;
 
        initial stb = 0;
 
        initial c_wr = 0;
 
        initial wr_cstb = 0;
 
        initial state = DC_IDLE;
 
        initial set_vflag = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
 
        if (i_reset)
        begin
        begin
 
                c_v <= 0;
 
                c_wr   <= 1'b0;
 
                c_wsel <= 4'hf;
 
                r_wb_cyc_gbl <= 1'b0;
 
                r_wb_cyc_lcl <= 1'b0;
 
                o_wb_stb_gbl <= 0;
 
                o_wb_stb_lcl <= 0;
 
                wr_cstb <= 1'b0;
 
                last_line_stb <= 1'b0;
 
                end_of_line <= 1'b0;
 
                state <= DC_IDLE;
 
                cyc <= 1'b0;
 
                stb <= 1'b0;
 
                state <= DC_IDLE;
 
                set_vflag <= 1'b0;
 
        end else begin
                // By default, update the cache from the write 1-clock ago
                // By default, update the cache from the write 1-clock ago
                c_wr <= (wr_cstb)&&(wr_wtag == wr_vtag);
                // c_wr <= (wr_cstb)&&(wr_wtag == wr_vtag);
                c_wdata <= wr_data;
                // c_waddr <= wr_addr[(CS-1):0];
                c_waddr <= wr_addr[(CS-1):0];
                c_wr <= 0;
 
 
 
                set_vflag <= 1'b0;
 
                if ((!cyc)&&(set_vflag))
 
                        c_v[c_waddr[(CS-1):LS]] <= 1'b1;
 
 
                wr_cstb <= 1'b0;
                wr_cstb <= 1'b0;
                wr_vtag <= c_vtags[o_wb_addr[(CS-LS-1):0]];
 
                wr_wtag <= o_wb_addr[(AW-LS-1):0];
 
                wr_data <= o_wb_data;
 
                wr_addr <= o_wb_addr[(CS-1):0];
 
 
 
 
                if (!cyc)
 
                        wr_addr <= r_addr[(CS-1):0];
 
                else if (i_wb_ack)
 
                        wr_addr <= wr_addr + 1'b1;
 
                else
 
                        wr_addr <= wr_addr;
 
 
                if (LS <= 1)
                if (LS <= 0)
                        end_of_line <= 1'b1;
                        end_of_line <= 1'b1;
 
                else if (!cyc)
 
                        end_of_line <= 1'b0;
 
                else if (!end_of_line)
 
                begin
 
                        if (i_wb_ack)
 
                                end_of_line
 
                                <= (c_waddr[(LS-1):0] == {{(LS-2){1'b1}},2'b01});
                else
                else
                        end_of_line<=(cyc)&&((c_waddr[(LS-1):1]=={(LS-1){1'b1}})
                                end_of_line
                                ||((i_wb_ack)
                                <= (c_waddr[(LS-1):0]=={{(LS-1){1'b1}}, 1'b0});
                                &&(c_waddr[(LS-1):0]=={{(LS-2){1'b1}},2'b01})));
                end
 
 
                if (LS <= 1)
                if (!cyc)
 
                        last_line_stb <= (LS <= 0);
 
                else if ((stb)&&(!i_wb_stall)&&(LS <= 1))
                        last_line_stb <= 1'b1;
                        last_line_stb <= 1'b1;
                else
                else if ((stb)&&(!i_wb_stall))
                        last_line_stb <= (stb)&&
                        last_line_stb <= (o_wb_addr[(LS-1):1]=={(LS-1){1'b1}});
                                ((o_wb_addr[(LS-1):1]=={(LS-1){1'b1}})
                else if (stb)
                                ||((!i_wb_stall)
                        last_line_stb <= (o_wb_addr[(LS-1):0]=={(LS){1'b1}});
                                        &&(o_wb_addr[(LS-1):0]
 
                                                =={{(LS-2){1'b1}},2'b01})));
 
 
 
                //
                //
                if (state == `DC_IDLE)
                //
                        pipeable_op <= 1'b0;
                if (state == DC_IDLE)
                if (state == `DC_IDLE)
 
                        non_pipeable_op <= 1'b0;
 
 
 
 
 
                if (state == `DC_IDLE)
 
                begin
                begin
                        o_wb_we <= 1'b0;
                        o_wb_we <= 1'b0;
                        o_wb_data <= i_data;
 
                        pipeable_op <= 1'b0;
 
                        non_pipeable_op <= 1'b1;
 
 
 
                        cyc <= 1'b0;
                        cyc <= 1'b0;
                        stb <= 1'b0;
                        stb <= 1'b0;
 
 
                        r_wb_cyc_gbl <= 1'b0;
                        r_wb_cyc_gbl <= 1'b0;
                        r_wb_cyc_lcl <= 1'b0;
                        r_wb_cyc_lcl <= 1'b0;
                        o_wb_stb_gbl <= 1'b0;
                        o_wb_stb_gbl <= 1'b0;
                        o_wb_stb_lcl <= 1'b0;
                        o_wb_stb_lcl <= 1'b0;
 
 
                        in_cache <= (i_op)&&(w_cachable);
                        in_cache <= (i_op[0])&&(w_cachable);
                        if ((i_pipe_stb)&&(i_op))
                        if ((i_pipe_stb)&&(i_op[0]))
                        begin // Write  operation
                        begin // Write  operation
                                state <= `DC_WRITE;
                                state <= DC_WRITE;
                                o_wb_addr <= i_addr;
                                o_wb_addr <= i_addr[(AW+1):2];
                                o_wb_we <= 1'b1;
                                o_wb_we <= 1'b1;
                                pipeable_op <= 1'b1;
 
 
 
                                cyc <= 1'b1;
                                cyc <= 1'b1;
                                stb <= 1'b1;
                                stb <= 1'b1;
 
 
                                r_wb_cyc_gbl <= (i_addr[31:30]!=2'b11);
                                if (OPT_LOCAL_BUS)
                                r_wb_cyc_lcl <= (i_addr[31:30]==2'b11);
                                begin
                                o_wb_stb_gbl <= (i_addr[31:30]!=2'b11);
                                r_wb_cyc_gbl <= (i_addr[DW-1:DW-8]!=8'hff);
                                o_wb_stb_lcl <= (i_addr[31:30]==2'b11);
                                r_wb_cyc_lcl <= (i_addr[DW-1:DW-8]==8'hff);
 
                                o_wb_stb_gbl <= (i_addr[DW-1:DW-8]!=8'hff);
 
                                o_wb_stb_lcl <= (i_addr[DW-1:DW-8]==8'hff);
 
                                end else begin
 
                                        r_wb_cyc_gbl <= 1'b1;
 
                                        o_wb_stb_gbl <= 1'b1;
 
                                end
 
 
                        end else if (r_cache_miss)
                        end else if (r_cache_miss)
                        begin
                        begin
                                state <= `DC_READC;
                                state <= DC_READC;
                                o_wb_addr <= { i_ctag, {(LS){1'b0}} };
                                o_wb_addr <= { r_ctag, {(LS){1'b0}} };
                                non_pipeable_op <= 1'b1;
 
 
 
 
                                c_waddr <= { r_ctag[CS-LS-1:0], {(LS){1'b0}} }-1'b1;
                                cyc <= 1'b1;
                                cyc <= 1'b1;
                                stb <= 1'b1;
                                stb <= 1'b1;
                                r_wb_cyc_gbl <= 1'b1;
                                r_wb_cyc_gbl <= 1'b1;
                                o_wb_stb_gbl <= 1'b1;
                                o_wb_stb_gbl <= 1'b1;
 
                                wr_addr[LS-1:0] <= 0;
                        end else if ((i_pipe_stb)&&(!w_cachable))
                        end else if ((i_pipe_stb)&&(!w_cachable))
                        begin // Read non-cachable memory area
                        begin // Read non-cachable memory area
                                state <= `DC_READS;
                                state <= DC_READS;
                                o_wb_addr <= i_addr;
                                o_wb_addr <= i_addr[(AW+1):2];
                                pipeable_op <= 1'b1;
 
 
 
                                cyc <= 1'b1;
                                cyc <= 1'b1;
                                stb <= 1'b1;
                                stb <= 1'b1;
                                r_wb_cyc_gbl <= (i_addr[31:30]!=2'b11);
                                if (OPT_LOCAL_BUS)
                                r_wb_cyc_lcl <= (i_addr[31:30]==2'b11);
                                begin
                                o_wb_stb_gbl <= (i_addr[31:30]!=2'b11);
                                r_wb_cyc_gbl <= (i_addr[DW-1:DW-8]!=8'hff);
                                o_wb_stb_lcl <= (i_addr[31:30]==2'b11);
                                r_wb_cyc_lcl <= (i_addr[DW-1:DW-8]==8'hff);
 
                                o_wb_stb_gbl <= (i_addr[DW-1:DW-8]!=8'hff);
 
                                o_wb_stb_lcl <= (i_addr[DW-1:DW-8]==8'hff);
 
                                end else begin
 
                                r_wb_cyc_gbl <= 1'b1;
 
                                o_wb_stb_gbl <= 1'b1;
 
                                end
                        end // else we stay idle
                        end // else we stay idle
 
 
                end else if (state == `DC_READC)
                end else if (state == DC_READC)
                begin
                begin
                        // We enter here once we have committed to reading
                        // We enter here once we have committed to reading
                        // data into a cache line.
                        // data into a cache line.
                        if ((stb)&&(!i_wb_stall))
                        if ((stb)&&(!i_wb_stall))
                        begin
                        begin
                                stb <= (!last_line_stb);
                                stb <= (!last_line_stb);
                                o_wb_stb_gbl <= (!last_line_stb);
                                o_wb_stb_gbl <= (!last_line_stb);
                                o_wb_addr[(LS-1):0] <= o_wb_addr[(LS-1):0]+1'b1;
                                o_wb_addr[(LS-1):0] <= o_wb_addr[(LS-1):0]+1'b1;
                        end
                        end
 
 
                        if(stb)
                        if ((i_wb_ack)&&(!end_of_line))
                                c_v[o_wb_addr[(CS-LS-1):0]] <= 1'b0;
                                c_v[o_wb_addr[(CS-1):LS]] <= 1'b0;
 
 
                        c_wr <= (i_wb_ack);
                        c_wr <= (i_wb_ack);
                        c_wdata <= o_wb_data;
                        c_wdata <= i_wb_data;
                        c_waddr <= ((c_wr)?(c_waddr+1'b1):c_waddr);
                        c_waddr <= ((i_wb_ack)?(c_waddr+1'b1):c_waddr);
 
                        c_wsel  <= 4'hf;
                        c_vtags[o_wb_addr[(CS-LS-1):0]]<= o_wb_addr[(AW-LS-1):0];
 
 
                        set_vflag <= !i_wb_err;
 
                        if (i_wb_ack)
 
                                c_vtags[r_addr[(CS-1):LS]]
 
                                                <= r_addr[(AW-1):LS];
 
 
                        if (((i_wb_ack)&&(end_of_line))||(i_wb_err))
                        if (((i_wb_ack)&&(end_of_line))||(i_wb_err))
                        begin
                        begin
                                state           <= `DC_IDLE;
                                state          <= DC_IDLE;
                                non_pipeable_op <= 1'b0;
 
                                cyc <= 1'b0;
                                cyc <= 1'b0;
 
                                stb <= 1'b0;
                                r_wb_cyc_gbl <= 1'b0;
                                r_wb_cyc_gbl <= 1'b0;
                                r_wb_cyc_lcl <= 1'b0;
                                r_wb_cyc_lcl <= 1'b0;
 
                                o_wb_stb_gbl <= 1'b0;
 
                                o_wb_stb_lcl <= 1'b0;
                                //
                                //
                                c_v[o_wb_addr[(CS-LS-1):0]] <= i_wb_ack;
 
                        end
                        end
                end else if (state == `DC_READS)
                end else if (state == DC_READS)
                begin
                begin
                        // We enter here once we have committed to reading
                        // We enter here once we have committed to reading
                        // data that cannot go into a cache line
                        // data that cannot go into a cache line
                        if ((!i_wb_stall)&&(!i_pipe_stb))
                        if ((!i_wb_stall)&&(!i_pipe_stb))
                        begin
                        begin
                                stb <= 1'b0;
                                stb <= 1'b0;
                                o_wb_stb_gbl <= 1'b0;
                                o_wb_stb_gbl <= 1'b0;
                                o_wb_stb_lcl <= 1'b0;
                                o_wb_stb_lcl <= 1'b0;
                                pipeable_op <= 1'b0;
 
                        end
                        end
 
 
                        if ((!i_wb_stall)&&(i_pipe_stb))
                        if ((!i_wb_stall)&&(i_pipe_stb))
                                o_wb_addr <= i_data;
                                o_wb_addr <= i_addr[(AW+1):2];
 
 
                        c_wr <= 1'b0;
                        c_wr <= 1'b0;
 
 
                        if (((i_wb_ack)&&(last_ack))||(i_wb_err))
                        if (((i_wb_ack)&&(last_ack))||(i_wb_err))
                        begin
                        begin
                                state        <= `DC_IDLE;
                                state        <= DC_IDLE;
                                cyc          <= 1'b0;
                                cyc          <= 1'b0;
 
                                stb          <= 1'b0;
                                r_wb_cyc_gbl <= 1'b0;
                                r_wb_cyc_gbl <= 1'b0;
                                r_wb_cyc_lcl <= 1'b0;
                                r_wb_cyc_lcl <= 1'b0;
 
                                o_wb_stb_gbl <= 1'b0;
 
                                o_wb_stb_lcl <= 1'b0;
                        end
                        end
                end else if (state == `DC_WRITE)
                end else if (state == DC_WRITE)
                begin
                begin
                        // c_wr    <= (c_v[])&&(c_tag[])&&(in_cache)&&(stb);
                        c_wr    <= (stb)&&(c_v[o_wb_addr[CS-1:LS]])
 
                                &&(c_vtags[o_wb_addr[CS-1:LS]]==o_wb_addr[AW-1:LS])
 
                                &&(stb);
                        c_wdata <= o_wb_data;
                        c_wdata <= o_wb_data;
                        c_waddr <= (state == `DC_IDLE)?i_caddr
                        c_waddr <= r_addr[CS-1:0];
                                : ((c_wr)?(c_waddr+1'b1):c_waddr);
                        c_wsel  <= o_wb_sel;
 
 
                        if ((!i_wb_stall)&&(!i_pipe_stb))
                        if ((!i_wb_stall)&&(!i_pipe_stb))
                        begin
                        begin
                                stb          <= 1'b0;
                                stb          <= 1'b0;
                                o_wb_stb_gbl <= 1'b0;
                                o_wb_stb_gbl <= 1'b0;
                                o_wb_stb_lcl <= 1'b0;
                                o_wb_stb_lcl <= 1'b0;
                                pipeable_op  <= 1'b0;
 
                        end
                        end
 
 
                        wr_cstb  <= (stb)&&(!i_wb_stall)&&(in_cache);
                        wr_cstb  <= (stb)&&(!i_wb_stall)&&(in_cache);
 
 
                        if ((stb)&&(!i_wb_stall)&&(i_pipe_stb))
                        if ((stb)&&(!i_wb_stall))
                                o_wb_addr <= i_addr;
                                o_wb_addr <= i_addr[(AW+1):2];
                        if ((stb)&&(!i_wb_stall)&&(i_pipe_stb))
 
                                o_wb_data <= i_data;
 
 
 
                        if (((i_wb_ack)&&(last_ack))||(i_wb_err))
                        if (((i_wb_ack)&&(last_ack)
 
                                                &&((!OPT_PIPE)||(!i_pipe_stb)))
 
                                ||(i_wb_err))
                        begin
                        begin
                                state        <= `DC_IDLE;
                                state        <= DC_IDLE;
                                cyc          <= 1'b0;
                                cyc          <= 1'b0;
 
                                stb          <= 1'b0;
                                r_wb_cyc_gbl <= 1'b0;
                                r_wb_cyc_gbl <= 1'b0;
                                r_wb_cyc_lcl <= 1'b0;
                                r_wb_cyc_lcl <= 1'b0;
 
                                o_wb_stb_gbl <= 1'b0;
 
                                o_wb_stb_lcl <= 1'b0;
                        end
                        end
                end
                end
        end
        end
 
 
        //
        //
 
        // npending is the number of outstanding (non-cached) read or write
 
        // requests
 
        initial npending = 0;
 
        always @(posedge i_clk)
 
        if ((i_reset)||(!OPT_PIPE)
 
                        ||((cyc)&&(i_wb_err))
 
                        ||((!cyc)&&(!i_pipe_stb))
 
                        ||(state == DC_READC))
 
                npending <= 0;
 
        else if (r_svalid)
 
                npending <= (i_pipe_stb) ? 1:0;
 
        else case({ (i_pipe_stb), (cyc)&&(i_wb_ack) })
 
        2'b01: npending <= npending - 1'b1;
 
        2'b10: npending <= npending + 1'b1;
 
        default: begin end
 
        endcase
 
 
 
        initial last_ack = 1'b0;
 
        always @(posedge i_clk)
 
        if (i_reset)
 
                last_ack <= 1'b0;
 
        else if (state == DC_IDLE)
 
        begin
 
                last_ack <= 1'b0;
 
                if ((i_pipe_stb)&&(i_op[0]))
 
                        last_ack <= 1'b1;
 
                else if (r_cache_miss)
 
                        last_ack <= (LS == 0);
 
                else if ((i_pipe_stb)&&(!w_cachable))
 
                        last_ack <= 1'b1;
 
        end else if (state == DC_READC)
 
        begin
 
                if (i_wb_ack)
 
                        last_ack <= last_ack || (&wr_addr[LS-1:1]);
 
                else
 
                        last_ack <= last_ack || (&wr_addr[LS-1:0]);
 
        end else case({ (i_pipe_stb), (i_wb_ack) })
 
        2'b01: last_ack <= (npending <= 2);
 
        2'b10: last_ack <= (!cyc)||(npending == 0);
 
        default: begin end
 
        endcase
 
 
 
`ifdef  FORMAL
 
always @(*)
 
`ASSERT(npending <= { 1'b1, {(DP){1'b0}} });
 
 
 
`endif
 
 
 
 
 
        //
        // Writes to the cache
        // Writes to the cache
        //
        //
        // These have been made as simple as possible.  Note that the c_wr
        // These have been made as simple as possible.  Note that the c_wr
        // line has already been determined, as have the write value and address
        // line has already been determined, as have the write value and address
        // on the last clock.  Further, this structure is defined to match the
        // on the last clock.  Further, this structure is defined to match the
        // block RAM design of as many architectures as possible.
        // block RAM design of as many architectures as possible.
        // 
        // 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (c_wr)
                if (c_wr)
                        c_mem[c_waddr] <= c_wdata;
        begin
 
                if (c_wsel[0])
 
                        c_mem[c_waddr][7:0] <= c_wdata[7:0];
 
                if (c_wsel[1])
 
                        c_mem[c_waddr][15:8] <= c_wdata[15:8];
 
                if (c_wsel[2])
 
                        c_mem[c_waddr][23:16] <= c_wdata[23:16];
 
                if (c_wsel[3])
 
                        c_mem[c_waddr][31:24] <= c_wdata[31:24];
 
        end
 
 
        //
        //
        // Reads from the cache
        // Reads from the cache
        //
        //
        // Some architectures require that all reads be registered.  We
        // Some architectures require that all reads be registered.  We
        // accomplish that here.  Whether or not the result of this read is
        // accomplish that here.  Whether or not the result of this read is
        // going to be our output will need to be determined with combinatorial
        // going to be our output will need to be determined with combinatorial
        // logic on the output.
        // logic on the output.
        //
        //
        reg     [31:0]   cached_idata, cached_rdata;
        generate if (OPT_DUAL_READ_PORT)
 
        begin
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                cached_idata <= c_mem[i_caddr];
                cached_idata <= c_mem[i_caddr];
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                cached_rdata <= c_mem[r_caddr];
                cached_rdata <= c_mem[r_caddr];
 
 
 
        end else begin
 
 
 
                always @(posedge i_clk)
 
                        cached_rdata <= c_mem[(o_busy) ? r_caddr : i_caddr];
 
 
 
                always @(*)
 
                        cached_idata = cached_rdata;
 
 
 
        end endgenerate
 
 
// o_data can come from one of three places:
// o_data can come from one of three places:
// 1. The cache, assuming the data was in the last cache line
// 1. The cache, assuming the data was in the last cache line
// 2. The cache, second clock, assuming the data was in the cache at all
// 2. The cache, second clock, assuming the data was in the cache at all
// 3. The cache, after filling the cache
// 3. The cache, after filling the cache
// 4. The wishbone state machine, upon reading the value desired.
// 4. The wishbone state machine, upon reading the value desired.
        always @(posedge i_clk)
        always @(*)
                if (r_svalid)
                if (r_svalid)
                        o_data <= cached_idata;
                        pre_data = cached_idata;
                else if ((i_wb_ack)&&(pipeable_op))
                else if (state == DC_READS)
                        o_data <= i_wb_data;
                        pre_data = i_wb_data;
                else
                else
                        o_data <= cached_rdata;
                        pre_data = cached_rdata;
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                o_valid <= (r_svalid)||((i_wb_ack)&&(pipeable_op))
        casez(req_data[3:0])
                                ||(r_dvalid)||(r_rvalid);
        4'b100?: o_data <= { 16'h0, pre_data[31:16] };
 
        4'b101?: o_data <= { 16'h0, pre_data[15: 0] };
 
        4'b1100: o_data <= { 24'h0, pre_data[31:24] };
 
        4'b1101: o_data <= { 24'h0, pre_data[23:16] };
 
        4'b1110: o_data <= { 24'h0, pre_data[15: 8] };
 
        4'b1111: o_data <= { 24'h0, pre_data[ 7: 0] };
 
        default o_data <= pre_data;
 
        endcase
 
 
 
        initial o_valid = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                o_err <= (cyc)&&(i_wb_err);
        if (i_reset)
 
                o_valid <= 1'b0;
 
        else if (state == DC_READS)
 
                o_valid <= i_wb_ack;
 
        else
 
                o_valid <= (r_svalid)||(r_dvalid);
 
 
        assign  o_busy = (state != `DC_IDLE);
        initial o_err = 1'b0;
 
        always @(posedge i_clk)
 
        if (i_reset)
 
                o_err <= 1'b0;
 
        else
 
                o_err <= (cyc)&&(i_wb_err);
 
 
 
        initial o_busy = 0;
 
        always @(posedge i_clk)
 
        if ((i_reset)||((cyc)&&(i_wb_err)))
 
                o_busy <= 1'b0;
 
        else if (i_pipe_stb)
 
                o_busy <= 1'b1;
 
        else if ((state == DC_READS)&&(i_wb_ack))
 
                o_busy <= 1'b0;
 
        else if ((r_rd_pending)&&(!r_dvalid))
 
                o_busy <= 1'b1;
 
        else if ((state == DC_WRITE)
 
                        &&(i_wb_ack)&&(last_ack)&&(!i_pipe_stb))
 
                o_busy <= 1'b0;
 
        else if (cyc)
 
                o_busy <= 1'b1;
 
        else // if ((r_dvalid)||(r_svalid))
 
                o_busy <= 1'b0;
 
 
        //
        //
        // Handle our auxilliary data lines.
        // We can use our FIFO addresses to pre-calculate when an ACK is going
 
        // to be the last_noncachable_ack.
 
 
 
 
 
        always @(*)
 
        if (OPT_PIPE)
 
                o_pipe_stalled = (cyc)&&((!o_wb_we)||(i_wb_stall)||(!stb))
 
                                ||(r_rd_pending)||(npending[DP]);
 
        else
 
                o_pipe_stalled = o_busy;
 
 
 
        initial lock_gbl = 0;
 
        initial lock_lcl = 0;
 
        always @(posedge i_clk)
 
        if (i_reset)
 
        begin
 
                lock_gbl <= 1'b0;
 
                lock_lcl<= 1'b0;
 
        end else begin
 
                lock_gbl <= (OPT_LOCK)&&(i_lock)&&((r_wb_cyc_gbl)||(lock_gbl));
 
                lock_lcl <= (OPT_LOCK)&&(i_lock)&&((r_wb_cyc_lcl)||(lock_lcl));
 
        end
 
 
 
        assign  o_wb_cyc_gbl = (r_wb_cyc_gbl)||(lock_gbl);
 
        assign  o_wb_cyc_lcl = (r_wb_cyc_lcl)||(lock_lcl);
 
 
 
        generate if (AW+2 < DW)
 
        begin : UNUSED_BITS
 
 
 
                // Verilator lint_off UNUSED
 
                wire    [DW-AW-2:0]      unused;
 
                assign  unused = i_addr[DW-1:AW+1];
 
                // Verilator lint_on  UNUSED
 
        end endgenerate
 
 
 
`ifdef  FORMAL
 
 
 
        initial f_past_valid = 1'b0;
 
        always @(posedge i_clk)
 
                f_past_valid <= 1'b1;
 
 
 
        ////////////////////////////////////////////////
        //
        //
        // These just go into a FIFO upon request, and then get fed back out
        // Reset properties
        // upon completion of an OP.
 
        //
        //
        // These are currently designed for handling bursts of writes or
        ////////////////////////////////////////////////
        // non-cachable  reads.
 
        //
        //
        // A very similar structure will be used once we switch to using an
 
        // MMU, in order to make certain memory operations are synchronous
 
        // enough to deal with bus errors.
 
        //
        //
        reg     [(LGAUX-1):0]    aux_head, aux_tail;
        always @(*)
        reg     [(NAUX-1):0]     aux_fifo [0:((1<<LGAUX)-1)];
        if(!f_past_valid)
        initial aux_head = 0;
                `ASSUME(i_reset);
        initial aux_tail = 0;
 
        always @(posedge i_clk)
        always @(posedge i_clk)
 
        if ((!f_past_valid)||($past(i_reset)))
        begin
        begin
                if ((i_rst)||(i_wb_err))
                // Insist on initial statements matching reset values
                        aux_head <= 0;
                `ASSERT(r_rd == 1'b0);
                else if ((i_pipe_stb)&&(!o_busy))
                `ASSERT(r_cachable == 1'b0);
                        aux_head <= aux_head + 1'b1;
                `ASSERT(r_svalid == 1'b0);
                aux_fifo[aux_head] <= i_oreg;
                `ASSERT(r_dvalid == 1'b0);
 
                `ASSERT(r_cache_miss == 1'b0);
 
                `ASSERT(r_addr == 0);
 
                //
 
                `ASSERT(c_wr == 0);
 
                `ASSERT(c_v  == 0);
 
                //
 
                // assert(aux_head == 0);
 
                // assert(aux_tail == 0);
 
                //
 
                `ASSERT(lock_gbl == 0);
 
                `ASSERT(lock_lcl == 0);
        end
        end
 
 
 
        ////////////////////////////////////////////////
 
        //
 
        // Assumptions about our inputs
 
        //
 
        ////////////////////////////////////////////////
 
        //
 
        //
 
        always @(*)
 
        if (o_pipe_stalled)
 
                `ASSUME(!i_pipe_stb);
 
 
 
        always @(*)
 
        if (!f_past_valid)
 
                `ASSUME(!i_pipe_stb);
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset))
 
                &&($past(i_pipe_stb))&&($past(o_pipe_stalled)))
        begin
        begin
                if ((i_rst)||(i_wb_err))
                `ASSUME($stable(i_pipe_stb));
                        aux_tail <= 0;
                `ASSUME($stable(i_op[0]));
                else if (o_valid) // ||(aux_tail[WBIT])&&(no-mmu-error)
                `ASSUME($stable(i_addr));
                        aux_tail <= aux_tail + 1'b1;
                if (i_op[0])
                o_wreg <= aux_fifo[aux_tail];
                        `ASSUME($stable(i_data));
        end
        end
 
 
 
        always @(posedge i_clk)
 
        if (o_err)
 
                `ASSUME(!i_pipe_stb);
 
 
 
        ////////////////////////////////////////////////
        //
        //
        // We can use our FIFO addresses to pre-calculate when an ACK is going
        // Wishbone properties
        // to be the last_noncachable_ack.
        //
 
        ////////////////////////////////////////////////
 
        //
 
        //
 
        wire    f_cyc, f_stb;
 
 
 
        assign  f_cyc = (o_wb_cyc_gbl)|(o_wb_cyc_lcl);
 
        assign  f_stb = (o_wb_stb_gbl)|(o_wb_stb_lcl);
 
 
 
        always @(*)
 
        begin
 
                // Only one interface can be active at once
 
                `ASSERT((!o_wb_cyc_gbl)||(!o_wb_cyc_lcl));
 
                // Strobe may only be active on the active interface
 
                `ASSERT((r_wb_cyc_gbl)||(!o_wb_stb_gbl));
 
                `ASSERT((r_wb_cyc_lcl)||(!o_wb_stb_lcl));
 
                if (o_wb_stb_lcl)
 
                begin
 
                        if (o_wb_we)
 
                                assert(state == DC_WRITE);
 
                        else
 
                                assert(state == DC_READS);
 
                end
 
 
 
                if (cyc)
 
                        assert(o_wb_we == (state == DC_WRITE));
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(cyc)&&($past(cyc)))
 
        begin
 
                `ASSERT($stable(r_wb_cyc_gbl));
 
                `ASSERT($stable(r_wb_cyc_lcl));
 
        end
 
 
 
 
        assign o_pipe_stalled=((pipeable_op)&&(i_wb_stall))||(non_pipeable_op);
`ifdef  DCACHE
        // pipeable_op must become zero when stb goes low
`define FWB_MASTER      fwb_master
 
`else
 
`define FWB_MASTER      fwb_counter
 
`endif
 
 
 
        `FWB_MASTER #(
 
                .AW(AW), .DW(DW),
 
                        .F_MAX_STALL(2),
 
                        .F_MAX_ACK_DELAY(3),
 
                        // If you need the proof to run faster, use these
 
                        // lines instead of the two that follow
 
                        // .F_MAX_STALL(1),
 
                        // .F_MAX_ACK_DELAY(1),
 
                        .F_LGDEPTH(F_LGDEPTH),
 
                        .F_MAX_REQUESTS((OPT_PIPE) ? 0 : (1<<LS)),
 
`ifdef  DCACHE
 
                        .F_OPT_SOURCE(1'b1),
 
`endif
 
                        .F_OPT_DISCONTINUOUS(0)
 
                ) fwb(i_clk, i_reset,
 
                        cyc, f_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
 
                                i_wb_ack, i_wb_stall, i_wb_data, i_wb_err,
 
                f_nreqs, f_nacks, f_outstanding);
 
 
 
`ifdef  DCACHE  // Arbitrary access is specific to local dcache implementation
 
        ////////////////////////////////////////////////
 
        //
 
        // Arbitrary address properties
 
        //
 
        ////////////////////////////////////////////////
 
        //
 
        //
 
        (* anyconst *)  reg     [AW:0]           f_const_addr;
 
        (* anyconst *)  reg                     f_const_buserr;
 
        wire    [AW-LS-1:0]      f_const_tag, f_ctag_here, f_wb_tag;
 
        wire    [CS-LS-1:0]      f_const_tag_addr;
 
        reg     [DW-1:0] f_const_data;
 
        wire    [DW-1:0] f_cmem_here;
 
        reg                     f_pending_rd;
 
        wire                    f_cval_in_cache;
 
 
 
        assign  f_const_tag    = f_const_addr[AW-1:LS];
 
        assign  f_const_tag_addr = f_const_addr[CS-1:LS];
 
        assign  f_cmem_here    = c_mem[f_const_addr[CS-1:0]];
 
        assign  f_ctag_here    = c_vtags[f_const_addr[CS-1:LS]];
 
        assign  f_wb_tag       = o_wb_addr[AW-1:LS];
 
 
 
        assign  f_cval_in_cache= (c_v[f_const_addr[CS-1:LS]])
 
                                        &&(f_ctag_here == f_const_tag);
 
 
 
        generate if ((AW > DW - 8)&&(OPT_LOCAL_BUS))
 
        begin : UPPER_CONST_ADDR_BITS
 
 
 
                always @(*)
 
                if (f_const_addr[AW])
 
                        assume(&f_const_addr[(AW-1):(DW-8)]);
 
                else
 
                        assume(!(&f_const_addr[(AW-1):(DW-8)]));
 
        end endgenerate
 
 
 
        wire    [AW-1:0] wb_start;
 
        assign  wb_start = (f_stb) ? (o_wb_addr - f_nreqs) : o_wb_addr;
 
 
 
        // Data changes upon request
        always @(posedge i_clk)
        always @(posedge i_clk)
        begin
        begin
                lock_gbl <= (i_lock)&&((r_wb_cyc_gbl)||(lock_gbl));
                if ((i_pipe_stb)&&(i_addr[(AW+1):2] == f_const_addr[AW-1:0])
                lock_lcl <= (i_lock)&&((r_wb_cyc_lcl)||(lock_lcl));
                        &&(f_const_addr[AW] == ((OPT_LOCAL_BUS)
 
                                                &&(&i_addr[(DW-1):(DW-8)])))
 
                        &&(i_op[0]))
 
                begin
 
                        casez({ i_op[2:1], i_addr[1:0] })
 
                        4'b0???: f_const_data <= i_data;
 
                        4'b100?: f_const_data[31:16] <= i_data[15:0];
 
                        4'b101?: f_const_data[15: 0] <= i_data[15:0];
 
                        4'b1100: f_const_data[31:24] <= i_data[ 7:0];
 
                        4'b1101: f_const_data[23:16] <= i_data[ 7:0];
 
                        4'b1110: f_const_data[15: 8] <= i_data[ 7:0];
 
                        4'b1111: f_const_data[ 7: 0] <= i_data[ 7:0];
 
                        endcase
        end
        end
 
 
        assign  o_wb_cyc_gbl = (r_wb_cyc_gbl)||(lock_gbl);
                if (f_cval_in_cache)
        assign  o_wb_cyc_lcl = (r_wb_cyc_lcl)||(lock_lcl);
                        assume((!i_wb_err)
 
                                ||(!i_pipe_stb)
 
                                ||(f_const_addr[AW-1:0] != i_addr[AW+1:2]));
 
        end
 
 
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!i_reset)&&(!f_const_buserr))
 
        begin
 
                if ((cyc)&&(o_wb_we)&&(f_stb)
 
                                &&(o_wb_addr[AW-1:0] == f_const_addr[AW-1:0])
 
                                &&( o_wb_stb_lcl == f_const_addr[AW]))
 
                begin
 
 
 
                        //
 
                        // Changing our data
 
                        //
 
                        if (o_wb_sel[0])
 
                                `ASSERT(o_wb_data[ 7: 0]==f_const_data[ 7: 0]);
 
                        if (o_wb_sel[1])
 
                                `ASSERT(o_wb_data[15: 8]==f_const_data[15: 8]);
 
                        if (o_wb_sel[2])
 
                                `ASSERT(o_wb_data[23:16]==f_const_data[23:16]);
 
                        if (o_wb_sel[3])
 
                                `ASSERT(o_wb_data[31:24]==f_const_data[31:24]);
 
 
 
                        // Check the data in the cache
 
                        if ((!f_const_addr[AW])&&(c_v[f_const_tag_addr])
 
                                &&(f_ctag_here == o_wb_addr[AW-1:LS]))
 
                        begin
 
                        if ((!c_wsel[0])&&(!o_wb_sel[0]))
 
                                `ASSERT(f_cmem_here[ 7: 0]==f_const_data[ 7: 0]);
 
                        if ((!c_wsel[1])&&(!o_wb_sel[1]))
 
                                `ASSERT(f_cmem_here[15: 8]==f_const_data[15: 8]);
 
                        if ((!c_wsel[2])&&(!o_wb_sel[2]))
 
                                `ASSERT(f_cmem_here[23:16]==f_const_data[23:16]);
 
                        if ((!c_wsel[3])&&(!o_wb_sel[3]))
 
                                `ASSERT(f_cmem_here[31:24]==f_const_data[31:24]);
 
 
 
                        end
 
                end else if ((!f_const_addr[AW])&&(c_v[f_const_tag_addr])
 
                        &&(f_ctag_here ==f_const_addr[AW-1:LS]))
 
                begin
 
                        // If ...
 
                        //   1. Our magic address is cachable
 
                        //   2. Our magic address is associated with a valid
 
                        //              cache line
 
                        //   3. The cache tag matches our magic address
 
 
 
 
 
                        // if ($past(cyc && i_wb_err))
 
                        // begin
 
                                // Ignore what happens on an error, the result
 
                                // becomes undefined anyway
 
                        // end else
 
                        if ((c_wr)
 
                                &&(c_waddr[CS-1:0] == f_const_addr[CS-1:0]))
 
                        begin
 
                                //
 
                                // If we are writing to this valid cache line
 
                                //
 
                                if (c_wsel[3])
 
                                        `ASSERT(c_wdata[31:24]
 
                                                        == f_const_data[31:24]);
 
                                else
 
                                        `ASSERT(f_cmem_here[31:24]
 
                                                        == f_const_data[31:24]);
 
                                if (c_wsel[2])
 
                                        `ASSERT(c_wdata[23:16]
 
                                                        == f_const_data[23:16]);
 
                                else
 
                                        `ASSERT(f_cmem_here[23:16] == f_const_data[23:16]);
 
                                if (c_wsel[1])
 
                                        `ASSERT(c_wdata[15:8]
 
                                                        == f_const_data[15:8]);
 
                                else
 
                                        `ASSERT(f_cmem_here[15:8] == f_const_data[15:8]);
 
                                if (c_wsel[0])
 
                                        `ASSERT(c_wdata[7:0]
 
                                                        == f_const_data[7:0]);
 
                                else
 
                                        `ASSERT(f_cmem_here[7:0] == f_const_data[7:0]);
 
                        end else
 
                                `ASSERT(f_cmem_here == f_const_data);
 
                end
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(state == DC_READC))
 
        begin
 
                `ASSERT(f_wb_tag == r_ctag);
 
                if ((wb_start[AW-1:LS] == f_const_tag)
 
                        &&(!c_v[f_const_tag_addr])
 
                        &&(f_const_addr[AW] == r_wb_cyc_lcl)
 
                        &&(f_nacks > f_const_addr[LS-1:0]))
 
                begin
 
                        // We are reading the cache line containing our
 
                        // constant address f_const_addr.  Make sure the data
 
                        // is correct.
 
                        if ((c_wr)&&(c_waddr[CS-1:0] == f_const_addr[CS-1:0]))
 
                                `ASSERT(c_wdata == f_const_data);
 
                        else
 
                                `ASSERT(f_cmem_here == f_const_data);
 
                end
 
 
 
                if (f_nacks > 0)
 
                        `ASSERT(!c_v[wb_start[CS-1:LS]]);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((state == DC_READC)&&(f_nacks > 0))
 
        begin
 
                `ASSERT(c_vtags[wb_start[(CS-1):LS]] <= wb_start[(AW-1):LS]);
 
                `ASSERT(c_vtags[wb_start[(CS-1):LS]] <= r_addr[AW-1:LS]);
 
        end
 
 
 
        reg     [AW-1:0] f_cache_waddr;
 
        wire                    f_this_cache_waddr;
 
 
 
        always @(*)
 
        begin
 
                // f_cache_waddr[AW-1:LS] = c_vtags[c_waddr[CS-1:CS-LS]];
 
                f_cache_waddr[AW-1:LS] = wb_start[AW-1:LS];
 
                f_cache_waddr[CS-1: 0] = c_waddr[CS-1:0];
 
        end
 
 
 
        assign  f_this_cache_waddr = (!f_const_addr[AW])
 
                                &&(f_cache_waddr == f_const_addr[AW-1:0]);
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(state == DC_READC))
 
        begin
 
                if ((c_wr)&&(c_waddr[LS-1:0] != 0)&&(f_this_cache_waddr))
 
                        `ASSERT(c_wdata == f_const_data);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((OPT_PIPE)&&(o_busy)&&(i_pipe_stb))
 
        begin
 
                `ASSUME(i_op[0] == o_wb_we);
 
                if (o_wb_cyc_lcl)
 
                        assume(&i_addr[DW-1:DW-8]);
 
                else
 
                        assume(!(&i_addr[DW-1:DW-8]));
 
        end
 
 
 
        initial f_pending_rd = 0;
 
        always @(posedge i_clk)
 
        if (i_reset)
 
                f_pending_rd <= 0;
 
        else if (i_pipe_stb)
 
                f_pending_rd <= (!i_op[0]);
 
        else if ((o_valid)&&((!OPT_PIPE)
 
                ||((state != DC_READS)&&(!r_svalid)&&(!$past(i_pipe_stb)))))
 
                f_pending_rd <= 1'b0;
 
 
 
        always @(*)
 
        if ((state == DC_READC)&&(!f_stb))
 
                `ASSERT(f_nreqs == (1<<LS));
 
 
 
        always @(*)
 
        if ((state == DC_READC)&&(f_stb))
 
                `ASSERT(f_nreqs == { 1'b0, o_wb_addr[LS-1:0] });
 
 
 
        always @(posedge i_clk)
 
        if (state == DC_READC)
 
        begin
 
                if (($past(i_wb_ack))&&(!$past(f_stb)))
 
                        `ASSERT(f_nacks-1 == { 1'b0, c_waddr[LS-1:0] });
 
                else if (f_nacks > 0)
 
                begin
 
                        `ASSERT(f_nacks-1 == { 1'b0, c_waddr[LS-1:0] });
 
                        `ASSERT(c_waddr[CS-1:LS] == o_wb_addr[CS-1:LS]);
 
                end else begin
 
                        `ASSERT(c_waddr[CS-1:LS] == o_wb_addr[CS-1:LS]-1'b1);
 
                        `ASSERT(&c_waddr[LS-1:0]);
 
                end
 
        end
 
 
 
        always @(*)
 
        if (r_rd_pending)
 
                `ASSERT(r_addr == f_pending_addr[AW-1:0]);
 
 
 
        always @(*)
 
        if (f_pending_addr[AW])
 
        begin
 
                `ASSERT(state != DC_READC);
 
                `ASSERT((!o_wb_we)||(!o_wb_cyc_gbl));
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(o_valid)&&($past(f_pending_addr) == f_const_addr))
 
        begin
 
                if (f_const_buserr)
 
                        `ASSERT(o_err);
 
                else if (f_pending_rd)
 
                begin
 
                        casez($past(req_data[3:0]))
 
                        4'b0???: `ASSERT(o_data ==f_const_data);
 
                        4'b101?: `ASSERT(o_data =={16'h00,f_const_data[15: 0]});
 
                        4'b100?: `ASSERT(o_data =={16'h00,f_const_data[31:16]});
 
                        4'b1100: `ASSERT(o_data =={24'h00,f_const_data[31:24]});
 
                        4'b1101: `ASSERT(o_data =={24'h00,f_const_data[23:16]});
 
                        4'b1110: `ASSERT(o_data =={24'h00,f_const_data[15: 8]});
 
                        4'b1111: `ASSERT(o_data =={24'h00,f_const_data[ 7: 0]});
 
                        endcase
 
                end
 
        end
 
 
 
        wire                    f_this_return;
 
 
 
        assign  f_this_return = (f_return_address == f_const_addr);
 
        always @(*)
 
        if ((f_cyc)&&(
 
                ((state == DC_READC)
 
                        &&(f_return_address[AW-1:LS] == f_const_addr[AW-1:LS]))
 
                ||(f_this_return))&&(f_cyc))
 
        begin
 
                if (f_const_buserr)
 
                        assume(!i_wb_ack);
 
                else begin
 
                        assume(!i_wb_err);
 
                        assume(i_wb_data == f_const_data);
 
                end
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(last_tag == f_const_tag)&&(f_const_buserr)
 
                        &&(!f_const_addr[AW]))
 
                `ASSERT(!last_tag_valid);
 
 
 
        always @(*)
 
        if (f_const_buserr)
 
        begin
 
                `ASSERT((!c_v[f_const_tag_addr])||(f_const_addr[AW])
 
                        ||(f_ctag_here != f_const_tag));
 
 
 
                if ((state == DC_READC)&&(wb_start[AW-1:LS] == f_const_tag))
 
                begin
 
                        `ASSERT(f_nacks <= f_const_tag[LS-1:0]);
 
                        if (f_nacks == f_const_tag[LS-1:0])
 
                                assume(!i_wb_ack);
 
                end
 
        end
 
 
 
`endif  // DCACHE
 
 
 
        ////////////////////////////////////////////////
 
        //
 
        // Checking the lock
 
        //
 
        ////////////////////////////////////////////////
 
        //
 
        //
 
 
 
        always @(*)
 
                `ASSERT((!lock_gbl)||(!lock_lcl));
 
        always @(*)
 
        if (!OPT_LOCK)
 
                `ASSERT((!lock_gbl)&&(!lock_lcl));
 
 
 
        ////////////////////////////////////////////////
 
        //
 
        // State based properties
 
        //
 
        ////////////////////////////////////////////////
 
        //
 
        //
 
        reg     [F_LGDEPTH-1:0]  f_rdpending;
 
 
 
        initial f_rdpending = 0;
 
        always @(posedge i_clk)
 
        if ((i_reset)||(o_err))
 
                f_rdpending <= 0;
 
        else case({ (i_pipe_stb)&&(!i_op[0]), o_valid })
 
        2'b01: f_rdpending <= f_rdpending - 1'b1;
 
        2'b10: f_rdpending <= f_rdpending + 1'b1;
 
        default: begin end
 
        endcase
 
 
 
        wire    f_wb_cachable;
 
        iscachable #(.ADDRESS_WIDTH(AW))
 
                f_chkwb_addr(o_wb_addr, f_wb_cachable);
 
 
 
 
 
        always @(*)
 
        if (state == DC_IDLE)
 
        begin
 
                `ASSERT(!r_wb_cyc_gbl);
 
                `ASSERT(!r_wb_cyc_lcl);
 
 
 
                `ASSERT(!cyc);
 
 
 
                if ((r_rd_pending)||(r_dvalid)||(r_svalid))
 
                        `ASSERT(o_busy);
 
 
 
                if (!OPT_PIPE)
 
                begin
 
                        if (r_rd_pending)
 
                                `ASSERT(o_busy);
 
                        else if (r_svalid)
 
                                `ASSERT(o_busy);
 
                        else if (o_valid)
 
                                `ASSERT(!o_busy);
 
                        else if (o_err)
 
                                `ASSERT(!o_busy);
 
                end
 
        end else begin
 
                `ASSERT(o_busy);
 
                `ASSERT(cyc);
 
        end
 
 
 
 
 
 
 
        always @(posedge i_clk)
 
        if (state == DC_IDLE)
 
        begin
 
                if (r_svalid)
 
                begin
 
                        `ASSERT(!r_dvalid);
 
                        `ASSERT(!r_rd_pending);
 
                        if (!OPT_PIPE)
 
                                `ASSERT(!o_valid);
 
                        else if (o_valid)
 
                                `ASSERT(f_rdpending == 2);
 
                end
 
 
 
                if (r_dvalid)
 
                begin
 
                        `ASSERT(!r_rd_pending);
 
                        `ASSERT(npending == 0);
 
                        `ASSERT(f_rdpending == 1);
 
                end
 
 
 
                if (r_rd_pending)
 
                begin
 
                        if ((OPT_PIPE)&&(o_valid))
 
                                `ASSERT(f_rdpending <= 2);
 
                        else
 
                                `ASSERT(f_rdpending == 1);
 
 
 
                end else if ((OPT_PIPE)&&(o_valid)&&($past(r_dvalid|r_svalid)))
 
                                `ASSERT(f_rdpending <= 2);
 
                else
 
                        `ASSERT(f_rdpending <= 1);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if (state == DC_READC)
 
        begin
 
                `ASSERT( o_wb_cyc_gbl);
 
                `ASSERT(!o_wb_cyc_lcl);
 
                `ASSERT(!o_wb_we);
 
                `ASSERT(f_wb_cachable);
 
 
 
                `ASSERT(r_rd_pending);
 
                `ASSERT(r_cachable);
 
                if (($past(cyc))&&(!$past(o_wb_stb_gbl)))
 
                        `ASSERT(!o_wb_stb_gbl);
 
 
 
                if ((OPT_PIPE)&&(o_valid))
 
                        `ASSERT(f_rdpending == 2);
 
                else
 
                        `ASSERT(f_rdpending == 1);
 
        end
 
 
 
        always @(*)
 
        if (state == DC_READS)
 
        begin
 
                `ASSERT(!o_wb_we);
 
 
 
                if (OPT_PIPE)
 
                begin
 
                        if (o_valid)
 
                                `ASSERT((f_rdpending == npending + 1)
 
                                        ||(f_rdpending == npending));
 
                        else
 
                                `ASSERT(f_rdpending == npending);
 
                end
 
        end else if (state == DC_WRITE)
 
                `ASSERT(o_wb_we);
 
 
 
        always @(posedge i_clk)
 
        if ((state == DC_READS)||(state == DC_WRITE))
 
        begin
 
                `ASSERT(o_wb_we == (state == DC_WRITE));
 
                `ASSERT(!r_rd_pending);
 
                if (o_wb_we)
 
                        `ASSERT(f_rdpending == 0);
 
 
 
                if (OPT_PIPE)
 
                begin
 
                        casez({ $past(i_pipe_stb), f_stb })
 
                        2'b00: `ASSERT(npending == f_outstanding);
 
                        2'b1?: `ASSERT(npending == f_outstanding + 1);
 
                        2'b01: `ASSERT(npending == f_outstanding + 1);
 
                        endcase
 
 
 
                        if (state == DC_WRITE)
 
                                `ASSERT(!o_valid);
 
                end else
 
                        `ASSERT(f_outstanding <= 1);
 
        end
 
 
 
        always @(*)
 
        if (OPT_PIPE)
 
                `ASSERT(f_rdpending <= 2);
 
        else
 
                `ASSERT(f_rdpending <= 1);
 
 
 
        always @(posedge i_clk)
 
        if ((!OPT_PIPE)&&(o_valid))
 
                `ASSERT(f_rdpending == 1);
 
        else if (o_valid)
 
                `ASSERT(f_rdpending >= 1);
 
 
 
 
 
        always @(*)
 
        if ((!o_busy)&&(!o_err)&&(!o_valid))
 
                `ASSERT(f_rdpending == 0);
 
 
 
        always @(*)
 
                `ASSERT(cyc == ((r_wb_cyc_gbl)||(r_wb_cyc_lcl)));
 
 
 
        always @(*)
 
        if ((!i_reset)&&(f_nreqs == f_nacks)&&(!f_stb))
 
                `ASSERT(!cyc);
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&($past(o_err)))
 
                `ASSUME(!i_lock);
 
        else if ((f_past_valid)&&(OPT_LOCK)&&($past(i_lock))
 
                        &&((!$past(o_valid)) || ($past(i_pipe_stb))))
 
                `ASSUME($stable(i_lock));
 
 
 
 
 
        ////////////////////////////////////////////////
 
        //
 
        // Ad-hoc properties
 
        //
 
        ////////////////////////////////////////////////
 
        //
 
        //
 
        always @(*)
 
        if ((OPT_PIPE)&&(state == DC_WRITE)&&(!i_wb_stall)&&(stb)
 
                        &&(!npending[DP]))
 
                `ASSERT(!o_pipe_stalled);
 
 
 
        always @(posedge i_clk)
 
        if (state == DC_WRITE)
 
                `ASSERT(o_wb_we);
 
        else if ((state == DC_READS)||(state == DC_READC))
 
                `ASSERT(!o_wb_we);
 
 
 
        always @(*)
 
        if (cyc)
 
                `ASSERT(f_cyc);
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(cyc))&&(!c_wr)&&(last_tag_valid)
 
                        &&(!r_rd_pending))
 
                `ASSERT((c_v[last_tag[(CS-LS-1):0]])
 
                        &&(c_vtags[last_tag[(CS-LS-1):0]] == last_tag));
 
 
 
        always @(*)
 
        if (!OPT_LOCAL_BUS)
 
        begin
 
                `ASSERT(r_wb_cyc_lcl == 1'b0);
 
                `ASSERT(o_wb_stb_lcl == 1'b0);
 
                `ASSERT(lock_lcl == 1'b0);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((state == DC_READC)&&(!stb))
 
        begin
 
                `ASSERT(o_wb_addr[LS-1:0] == 0);
 
                `ASSERT(o_wb_addr[AW-1:CS] == r_addr[AW-1:CS]);
 
        end else if ((state == DC_READC)&&(stb))
 
        begin
 
                `ASSERT(o_wb_addr[AW-1:CS] == r_addr[AW-1:CS]);
 
                `ASSERT(o_wb_addr[LS-1:0] == f_nreqs[LS-1:0]);
 
        end
 
 
 
        wire    [CS-1:0] f_expected_caddr;
 
        assign  f_expected_caddr = { r_ctag[CS-LS-1:0], {(LS){1'b0}} }-1
 
                                        + f_nacks;
 
        always @(posedge i_clk)
 
        if (state == DC_READC)
 
        begin
 
                if (LS == 0)
 
                        `ASSERT(end_of_line);
 
                else if (f_nacks < (1<<LS)-1)
 
                        `ASSERT(!end_of_line);
 
                else if (f_nacks == (1<<LS)-1)
 
                        `ASSERT(end_of_line);
 
                `ASSERT(f_nacks <= (1<<LS));
 
                `ASSERT(f_nreqs <= (1<<LS));
 
                if (f_nreqs < (1<<LS))
 
                begin
 
                        `ASSERT(o_wb_stb_gbl);
 
                        `ASSERT(o_wb_addr[(LS-1):0] == f_nreqs[LS-1:0]);
 
                end else
 
                        `ASSERT(!f_stb);
 
                `ASSERT((f_nreqs == 0)||(f_nacks <= f_nreqs));
 
                `ASSERT(c_waddr == f_expected_caddr);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(r_rd)&&(!$past(i_reset)))
 
        begin
 
                `ASSERT((o_busy)||(r_svalid));
 
        end
 
 
 
        always @(posedge i_clk)
 
        if (!$past(o_busy))
 
                `ASSERT(!r_dvalid);
 
 
 
        always @(posedge i_clk)
 
        if ((state == DC_READC)&&(c_wr))
 
                `ASSERT(c_wsel == 4'hf);
 
 
 
        always @(*)
 
        if (c_wr)
 
                `ASSERT((c_wsel == 4'hf)
 
                        ||(c_wsel == 4'hc)
 
                        ||(c_wsel == 4'h3)
 
                        ||(c_wsel == 4'h8)
 
                        ||(c_wsel == 4'h4)
 
                        ||(c_wsel == 4'h2)
 
                        ||(c_wsel == 4'h1));
 
 
 
        always @(*)
 
        if (!OPT_PIPE)
 
                `ASSERT(o_pipe_stalled == o_busy);
 
        else if (o_pipe_stalled)
 
                `ASSERT(o_busy);
 
 
 
        //
 
        // Only ever abort on reset
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(i_reset))&&($past(cyc))&&(!$past(i_wb_err)))
 
        begin
 
                if (($past(i_pipe_stb))&&(!$past(o_pipe_stalled)))
 
                        `ASSERT(cyc);
 
                else if ($past(f_outstanding > 1))
 
                        `ASSERT(cyc);
 
                else if (($past(f_outstanding == 1))
 
                                &&((!$past(i_wb_ack))
 
                                        ||(($past(f_stb))
 
                                                &&(!$past(i_wb_stall)))))
 
                        `ASSERT(cyc);
 
                else if (($past(f_outstanding == 0))
 
                                &&($past(f_stb)&&(!$past(i_wb_ack))))
 
                        `ASSERT(cyc);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((OPT_PIPE)&&(f_past_valid)&&(!$past(i_reset))&&(state != DC_READC))
 
        begin
 
                if ($past(cyc && i_wb_err))
 
                begin
 
                        `ASSERT(npending == 0);
 
                end else if (($past(i_pipe_stb))||($past(i_wb_stall && stb)))
 
                        `ASSERT((npending == f_outstanding+1)
 
                                ||(npending == f_outstanding+2));
 
                else
 
                        `ASSERT(npending == f_outstanding);
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((OPT_PIPE)&&(state != DC_READC)&&(state != DC_IDLE))
 
                `ASSERT(last_ack == (npending <= 1));
 
 
 
        always @(*)
 
        `ASSERT(stb == f_stb);
 
 
 
        always @(*)
 
        if (r_rd_pending)
 
                `ASSERT(!r_svalid);
 
 
 
        always @(*)
 
        if (o_err)
 
                `ASSUME(!i_pipe_stb);
 
 
 
        always @(*)
 
        if (last_tag_valid)
 
                `ASSERT(|c_v);
 
 
 
        always @(posedge i_clk)
 
        if ((cyc)&&(state == DC_READC)&&($past(f_nacks > 0)))
 
                `ASSERT(!c_v[o_wb_addr[CS-1:LS]]);
 
 
 
        always @(*)
 
        if (last_tag_valid)
 
        begin
 
                `ASSERT((!cyc)||(o_wb_we)||(state == DC_READS)
 
                                        ||(o_wb_addr[AW-1:LS] != last_tag));
 
        end
 
 
 
        wire    f_cachable_last_tag, f_cachable_r_addr;
 
 
 
        iscachable #(.ADDRESS_WIDTH(AW))
 
                fccheck_last_tag({last_tag, {(LS){1'b0}}}, f_cachable_last_tag);
 
 
 
        iscachable #(.ADDRESS_WIDTH(AW))
 
                fccheck_r_cachable(r_addr, f_cachable_r_addr);
 
 
 
        always @(*)
 
        if ((r_cachable)&&(r_rd_pending))
 
        begin
 
                `ASSERT(state != DC_WRITE);
 
                // `ASSERT(state != DC_READS);
 
                `ASSERT(f_cachable_r_addr);
 
                if (cyc)
 
                        `ASSERT(o_wb_addr[AW-1:LS] == r_addr[AW-1:LS]);
 
        end
 
 
 
        always @(*)
 
        if (last_tag_valid)
 
        begin
 
                `ASSERT(f_cachable_last_tag);
 
                `ASSERT(c_v[last_tag[CS-LS-1:0]]);
 
                `ASSERT(c_vtags[last_tag[CS-LS-1:0]]==last_tag);
 
                `ASSERT((state != DC_READC)||(last_tag != o_wb_addr[AW-1:LS]));
 
        end
 
 
 
 
 
        ////////////////////////////////////////////////
 
        //
 
        // Cover statements
 
        //
 
        ////////////////////////////////////////////////
 
        //
 
        //
 
 
 
        always @(posedge i_clk)
 
                cover(o_valid);
 
 
 
        always @(posedge i_clk)
 
        if (f_past_valid)
 
                cover($past(r_svalid));
 
 
 
        generate if (OPT_PIPE)
 
        begin : PIPE_COVER
 
 
 
                wire            recent_reset;
 
                reg     [2:0]    recent_reset_sreg;
 
                initial recent_reset_sreg = -1;
 
                always @(posedge i_clk)
 
                if (i_reset)
 
                        recent_reset_sreg <= -1;
 
                else
 
                        recent_reset_sreg <= { recent_reset_sreg[1:0], 1'b0 };
 
 
 
                assign recent_reset = (i_reset)||(|recent_reset_sreg);
 
 
 
                //
 
                //
 
                wire    f_cvr_cread = (!recent_reset)&&(i_pipe_stb)&&(!i_op[0])
 
                                        &&(w_cachable);
 
 
 
                wire    f_cvr_cwrite = (!recent_reset)&&(i_pipe_stb)&&(i_op[0])
 
                                &&(!cache_miss_inow);
 
 
 
                wire    f_cvr_writes = (!recent_reset)&&(i_pipe_stb)&&(i_op[0])
 
                                        &&(!w_cachable);
 
                wire    f_cvr_reads  = (!recent_reset)&&(i_pipe_stb)&&(!i_op[0])
 
                                        &&(!w_cachable);
 
                wire    f_cvr_test  = (!recent_reset)&&(cyc);
 
 
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&($past(o_valid)))
 
                        cover(o_valid);         // !
 
 
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&(!$past(i_reset))&&($past(i_pipe_stb)))
 
                        cover(i_pipe_stb);
 
 
 
                always @(posedge i_clk)
 
                if ((f_past_valid)&&($past(o_valid))&&($past(o_valid,2)))
 
                        cover(o_valid);
 
 
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_cread))&&(f_cvr_cread));
 
 
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_cwrite))&&(f_cvr_cwrite));
 
 
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_writes))&&(f_cvr_writes));
 
 
 
                /*
 
                * This cover statement will never pass.  Why not?  Because
 
                * cache reads must be separated from non-cache reads.  Hence,
 
                * we can only allow a single non-cache read at a time, otherwise
 
                * we'd bypass the cache read logic.
 
                *
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_reads))&&(f_cvr_reads));
 
                */
 
 
 
                //
 
                // This is unrealistic, as it depends upon the Wishbone
 
                // acknoledging the request on the same cycle
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_reads,2))&&(f_cvr_reads));
 
 
 
                always @(posedge i_clk)
 
                        cover(($past(r_dvalid))&&(r_svalid));
 
 
 
                //
 
                // A minimum of one clock must separate two dvalid's.
 
                // This option is rather difficult to cover, since it means
 
                // we must first load two separate cache lines before
 
                // this can even be tried.
 
                always @(posedge i_clk)
 
                        cover(($past(r_dvalid,2))&&(r_dvalid));
 
 
 
                //
 
                // This is the optimal configuration we want:
 
                //      i_pipe_stb
 
                //      ##1 i_pipe_stb && r_svalid
 
                //      ##1 r_svalid && o_valid
 
                //      ##1 o_valid
 
                // It proves that we can handle a 2 clock delay, but that
 
                // we can also pipelin these cache accesses, so this
 
                // 2-clock delay becomes a 1-clock delay between pipelined
 
                // memory reads.
 
                //
 
                always @(posedge i_clk)
 
                        cover(($past(r_svalid))&&(r_svalid));
 
 
 
                //
 
                // While we'd never do this (it breaks the ZipCPU's pipeline
 
                // rules), it's nice to know we could.
 
                //      i_pipe_stb && (!i_op[0]) // a read
 
                //      ##1 i_pipe_stb && (i_op[0]) && r_svalid // a write
 
                //      ##1 o_valid
 
                always @(posedge i_clk)
 
                        cover(($past(r_svalid))&&(f_cvr_writes));
 
 
 
                /* Unreachable
 
                *
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_writes))&&(o_valid));
 
 
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_writes,2))&&(o_valid));
 
 
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_writes,3))&&(o_valid));
 
 
 
                always @(posedge i_clk)
 
                        cover(($past(r_dvalid,3))&&(r_dvalid));
 
 
 
                */
 
 
 
                always @(posedge i_clk)
 
                        cover(($past(f_cvr_writes,4))&&(o_valid));
 
 
 
        end endgenerate
 
 
 
        ////////////////////////////////////////////////
 
        //
 
        // Carelesss assumption section
 
        //
 
        ////////////////////////////////////////////////
 
        //
 
        //
 
 
 
        //
 
        // Can't jump from local to global mid lock
 
        always @(*)
 
        if((OPT_LOCK)&&(OPT_LOCAL_BUS))
 
        begin
 
                if ((i_lock)&&(o_wb_cyc_gbl)&&(i_pipe_stb))
 
                        assume(!(&i_addr[(DW-1):(DW-8)]));
 
                else if ((i_lock)&&(o_wb_cyc_lcl)&&(i_pipe_stb))
 
                        assume(&i_addr[(DW-1):(DW-8)]);
 
        end
 
 
 
        always @(*)
 
        if ((OPT_PIPE)&&(o_busy || i_lock)&&(!o_pipe_stalled))
 
        begin
 
                if (i_pipe_stb)
 
                        assume((!OPT_LOCAL_BUS)
 
                                ||(f_pending_addr[AW]==(&i_addr[DW-1:DW-8])));
 
        end
 
 
 
        always @(posedge i_clk)
 
        if ((f_past_valid)&&(!$past(cyc))&&(!cyc))
 
                assume((!i_wb_err)&&(!i_wb_ack));
 
 
 
`endif
endmodule
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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