data/full_repos/permissive/137045072/inst_cache.v
1: b'%Error: data/full_repos/permissive/137045072/inst_cache.v:28: Cannot find include file: defines.v\n`include "defines.v" \n         ^~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/137045072,data/full_repos/permissive/137045072/defines.v\n             data/full_repos/permissive/137045072,data/full_repos/permissive/137045072/defines.v.v\n             data/full_repos/permissive/137045072,data/full_repos/permissive/137045072/defines.v.sv\n             defines.v\n             defines.v.v\n             defines.v.sv\n             obj_dir/defines.v\n             obj_dir/defines.v.v\n             obj_dir/defines.v.sv\n%Error: data/full_repos/permissive/137045072/inst_cache.v:43: Define or directive not defined: \'`DATA_BUS\'\n    input [`DATA_BUS] addr,  \n           ^~~~~~~~~\n%Error: data/full_repos/permissive/137045072/inst_cache.v:43: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    input [`DATA_BUS] addr,  \n                    ^\n%Error: data/full_repos/permissive/137045072/inst_cache.v:48: Define or directive not defined: \'`DATA_BUS\'\n    output reg [`DATA_BUS] data,\n                ^~~~~~~~~\n%Error: data/full_repos/permissive/137045072/inst_cache.v:52: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg [`DATA_BUS] mem_addr,\n    ^~~~~~\n%Error: data/full_repos/permissive/137045072/inst_cache.v:52: Define or directive not defined: \'`DATA_BUS\'\n    output reg [`DATA_BUS] mem_addr,\n                ^~~~~~~~~\n%Error: data/full_repos/permissive/137045072/inst_cache.v:55: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input [`DATA_BUS] mem_read,\n    ^~~~~\n%Error: data/full_repos/permissive/137045072/inst_cache.v:55: Define or directive not defined: \'`DATA_BUS\'\n    input [`DATA_BUS] mem_read,\n           ^~~~~~~~~\n%Error: data/full_repos/permissive/137045072/inst_cache.v:93: Define or directive not defined: \'`DATA_BUS\'\n    reg [`DATA_BUS] blocks[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1][0:BLOCK_SIZE-1];  \n         ^~~~~~~~~\n%Error: data/full_repos/permissive/137045072/inst_cache.v:93: syntax error, unexpected \']\', expecting TYPE-IDENTIFIER\n    reg [`DATA_BUS] blocks[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1][0:BLOCK_SIZE-1];  \n                  ^\n%Error: data/full_repos/permissive/137045072/inst_cache.v:96: syntax error, unexpected assign\n    assign ready = state == STATE_READY;\n    ^~~~~~\n%Error: data/full_repos/permissive/137045072/inst_cache.v:102: syntax error, unexpected always\n    always @*\n    ^~~~~~\n%Error: Exiting due to 12 error(s)\n'
module inst_cache#(
    parameter DATA_WIDTH = 32,
    parameter DATA_PER_BYTE_WIDTH = 2,

    parameter ASSO_WIDTH = 1,
    parameter BLOCK_OFFSET_WIDTH = 5,
    parameter INDEX_WIDTH = 3,
    parameter TAG_WIDTH = DATA_WIDTH - INDEX_WIDTH - BLOCK_OFFSET_WIDTH - DATA_PER_BYTE_WIDTH
)(
    input clk,
    input rst_n,


    input [`DATA_BUS] addr,
    input enable,
    

    output ready,
    output reg [`DATA_BUS] data,
    output reg data_valid,


    output reg [`DATA_BUS] mem_addr,
    output reg mem_enable,

    input [`DATA_BUS] mem_read,
    input mem_read_valid,
    
    input mem_last
    );


    localparam ASSOCIATIVITY = 1 << ASSO_WIDTH;
    localparam BLOCK_SIZE = 1 << BLOCK_OFFSET_WIDTH;
    localparam INDEX_SIZE = 1 << INDEX_WIDTH;


    localparam STATE_READY = 0;
    localparam STATE_MISS = 1;


    integer i, j, k;

    reg [1:0] state;
    reg [1:0] next_state;


    wire [TAG_WIDTH         -1:0] tag  = addr[DATA_WIDTH-1:INDEX_WIDTH+BLOCK_OFFSET_WIDTH+DATA_PER_BYTE_WIDTH];
    wire [INDEX_WIDTH       -1:0] block_index  = addr[INDEX_WIDTH+BLOCK_OFFSET_WIDTH+DATA_PER_BYTE_WIDTH-1:BLOCK_OFFSET_WIDTH+DATA_PER_BYTE_WIDTH];
    wire [BLOCK_OFFSET_WIDTH-1:0] block_offset = addr[BLOCK_OFFSET_WIDTH+DATA_PER_BYTE_WIDTH-1:DATA_PER_BYTE_WIDTH];
    reg  [ASSO_WIDTH        -1:0] location;


    reg  [TAG_WIDTH         -1:0] tag_reg;
    reg  [INDEX_WIDTH       -1:0] block_index_reg;
    reg  [BLOCK_OFFSET_WIDTH-1:0] block_offset_reg;
    reg  [ASSO_WIDTH        -1:0] location_reg;

    reg [BLOCK_OFFSET_WIDTH-1:0] write_cnt;


    reg [ASSO_WIDTH-1:0] timestamp[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1];
    reg [TAG_WIDTH-1:0] tags[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1];
    reg [`DATA_BUS] blocks[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1][0:BLOCK_SIZE-1];
    reg valid[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1];

    assign ready = state == STATE_READY;
    
    localparam LOCATION_X = {ASSO_WIDTH{1'bx}};
    localparam TAG_X = {TAG_WIDTH{1'bx}};


    always @*
    begin
        location = LOCATION_X;

        for (i = 0; i < ASSOCIATIVITY; i = i + 1)
            if (tags[block_index][i] == tag)
                location = i;
        if (location === LOCATION_X)

            for (i = 0; i < ASSOCIATIVITY; i = i + 1)
                if (tags[block_index][i] === TAG_X)
                    location = i;
        if (location === LOCATION_X)

            for (i = 0; i < ASSOCIATIVITY; i = i + 1)
                if (timestamp[block_index][i] == {ASSO_WIDTH{1'b1}})
                    location = i;
        

    end

    always @*
    begin
        next_state <= state;
        data_valid <= 0;
        data <= 'bx;
        mem_enable <= 0;
        mem_addr <= 'bx;

        case (state)
            STATE_READY: begin
                if (enable)
                begin
                    if (valid[block_index][location] && tags[block_index][location] == tag)
                    begin
                        data_valid <= 1;

                        data <= blocks[block_index][location][block_offset];
                        
                        timestamp[block_index][location] <= 0;
                        for (i = 0; i < ASSOCIATIVITY; i = i + 1)
                            if (timestamp[block_index][i] < timestamp[block_index][location])
                                timestamp[block_index][i] <= timestamp[block_index][i] + 1;
                    end
                    else
                    begin
`ifdef DEBUG_INST
                        $display("Inst cache miss on addr %x", addr);
`endif

                        next_state <= STATE_MISS;
                    end
                end
                else
                begin

                end
            end
            STATE_MISS: begin

                mem_enable <= 1;



                mem_addr <= {tag_reg, block_index_reg, {BLOCK_OFFSET_WIDTH{1'b0}}, {DATA_PER_BYTE_WIDTH{1'b0}}};

                if (mem_read_valid)
                begin

                    if (write_cnt == block_offset_reg)
                    begin
                        data_valid <= 1;
                        data <= mem_read;
                    end


                    if (mem_last)
                    begin
                        next_state <= STATE_READY;
                                            
                        timestamp[block_index_reg][location_reg] <= 0;
                        for (i = 0; i < ASSOCIATIVITY; i = i + 1)
                            if (timestamp[block_index_reg][i] < timestamp[block_index_reg][location_reg])
                                timestamp[block_index_reg][i] <= timestamp[block_index_reg][i] + 1;
                    end
                end
            end
        endcase
    end
      

    always @(posedge clk, negedge rst_n)
    begin
        if (!rst_n)
        begin
            write_cnt <= 0;
            block_offset_reg <= 0;
            block_index_reg <= 0;
            tag_reg <= 0;
            location_reg <= 0;
            
            for (i = 0; i < INDEX_SIZE; i = i + 1)
                for (j = 0; j < ASSOCIATIVITY; j = j + 1)
                begin
                    tags[i][j] <= TAG_X;
                    valid[i][j] <= 0;
                    timestamp[i][j] <= j;
                    for (k = 0; k < BLOCK_SIZE; k = k + 1)
                        blocks[i][j][k] <= 0;
                end
            state <= STATE_READY;
        end
        else
        begin
            state <= next_state;

            case (state)
                STATE_READY: begin
                    if (next_state == STATE_MISS)
                    begin
                        write_cnt <= 0;


                        block_offset_reg <= block_offset;
                        block_index_reg <= block_index;
                        tag_reg <= tag;
                        location_reg <= location;
                    end
                end
                STATE_MISS: begin
                    if (next_state == STATE_READY)
                    begin

                        tags[block_index_reg][location_reg] <= tag_reg;
                        valid[block_index_reg][location_reg] <= 1;
                    end


                    if (mem_read_valid)
                    begin
                        write_cnt <= write_cnt + 1;
                        blocks[block_index_reg][location_reg][write_cnt] <= mem_read;
                    end
                end
            endcase
        end
    end
endmodule
module inst_cache#(
    parameter DATA_WIDTH = 32,
    parameter DATA_PER_BYTE_WIDTH = 2,

    parameter ASSO_WIDTH = 1,
    parameter BLOCK_OFFSET_WIDTH = 5,
    parameter INDEX_WIDTH = 3,
    parameter TAG_WIDTH = DATA_WIDTH - INDEX_WIDTH - BLOCK_OFFSET_WIDTH - DATA_PER_BYTE_WIDTH
)(
    input clk,
    input rst_n,


    input [`DATA_BUS] addr,
    input enable,
    

    output ready,
    output reg [`DATA_BUS] data,
    output reg data_valid,


    output reg [`DATA_BUS] mem_addr,
    output reg mem_enable,

    input [`DATA_BUS] mem_read,
    input mem_read_valid,
    
    input mem_last
    );



    localparam ASSOCIATIVITY = 1 << ASSO_WIDTH;
    localparam BLOCK_SIZE = 1 << BLOCK_OFFSET_WIDTH;
    localparam INDEX_SIZE = 1 << INDEX_WIDTH;


    localparam STATE_READY = 0;
    localparam STATE_MISS = 1;


    integer i, j, k;

    reg [1:0] state;
    reg [1:0] next_state;


    wire [TAG_WIDTH         -1:0] tag  = addr[DATA_WIDTH-1:INDEX_WIDTH+BLOCK_OFFSET_WIDTH+DATA_PER_BYTE_WIDTH];
    wire [INDEX_WIDTH       -1:0] block_index  = addr[INDEX_WIDTH+BLOCK_OFFSET_WIDTH+DATA_PER_BYTE_WIDTH-1:BLOCK_OFFSET_WIDTH+DATA_PER_BYTE_WIDTH];
    wire [BLOCK_OFFSET_WIDTH-1:0] block_offset = addr[BLOCK_OFFSET_WIDTH+DATA_PER_BYTE_WIDTH-1:DATA_PER_BYTE_WIDTH];
    reg  [ASSO_WIDTH        -1:0] location;


    reg  [TAG_WIDTH         -1:0] tag_reg;
    reg  [INDEX_WIDTH       -1:0] block_index_reg;
    reg  [BLOCK_OFFSET_WIDTH-1:0] block_offset_reg;
    reg  [ASSO_WIDTH        -1:0] location_reg;

    reg [BLOCK_OFFSET_WIDTH-1:0] write_cnt;


    reg [ASSO_WIDTH-1:0] timestamp[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1];
    reg [TAG_WIDTH-1:0] tags[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1];
    reg [`DATA_BUS] blocks[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1][0:BLOCK_SIZE-1];
    reg valid[0:INDEX_SIZE-1][0:ASSOCIATIVITY-1];

    assign ready = state == STATE_READY;
    
    localparam LOCATION_X = {ASSO_WIDTH{1'bx}};
    localparam TAG_X = {TAG_WIDTH{1'bx}};


    always @*
    begin
        location = LOCATION_X;

        for (i = 0; i < ASSOCIATIVITY; i = i + 1)
            if (tags[block_index][i] == tag)
                location = i;
        if (location === LOCATION_X)

            for (i = 0; i < ASSOCIATIVITY; i = i + 1)
                if (tags[block_index][i] === TAG_X)
                    location = i;
        if (location === LOCATION_X)

            for (i = 0; i < ASSOCIATIVITY; i = i + 1)
                if (timestamp[block_index][i] == {ASSO_WIDTH{1'b1}})
                    location = i;
        

    end

    always @*
    begin
        next_state <= state;
        data_valid <= 0;
        data <= 'bx;
        mem_enable <= 0;
        mem_addr <= 'bx;

        case (state)
            STATE_READY: begin
                if (enable)
                begin
                    if (valid[block_index][location] && tags[block_index][location] == tag)
                    begin
                        data_valid <= 1;

                        data <= blocks[block_index][location][block_offset];
                        
                        timestamp[block_index][location] <= 0;
                        for (i = 0; i < ASSOCIATIVITY; i = i + 1)
                            if (timestamp[block_index][i] < timestamp[block_index][location])
                                timestamp[block_index][i] <= timestamp[block_index][i] + 1;
                    end
                    else
                    begin
`ifdef DEBUG_INST
                        $display("Inst cache miss on addr %x", addr);
`endif

                        next_state <= STATE_MISS;
                    end
                end
                else
                begin

                end
            end
            STATE_MISS: begin

                mem_enable <= 1;



                mem_addr <= {tag_reg, block_index_reg, {BLOCK_OFFSET_WIDTH{1'b0}}, {DATA_PER_BYTE_WIDTH{1'b0}}};

                if (mem_read_valid)
                begin

                    if (write_cnt == block_offset_reg)
                    begin
                        data_valid <= 1;
                        data <= mem_read;
                    end


                    if (mem_last)
                    begin
                        next_state <= STATE_READY;
                                            
                        timestamp[block_index_reg][location_reg] <= 0;
                        for (i = 0; i < ASSOCIATIVITY; i = i + 1)
                            if (timestamp[block_index_reg][i] < timestamp[block_index_reg][location_reg])
                                timestamp[block_index_reg][i] <= timestamp[block_index_reg][i] + 1;
                    end
                end
            end
        endcase
    end
      

    always @(posedge clk, negedge rst_n)
    begin
        if (!rst_n)
        begin
            write_cnt <= 0;
            block_offset_reg <= 0;
            block_index_reg <= 0;
            tag_reg <= 0;
            location_reg <= 0;
            
            for (i = 0; i < INDEX_SIZE; i = i + 1)
                for (j = 0; j < ASSOCIATIVITY; j = j + 1)
                begin
                    tags[i][j] <= TAG_X;
                    valid[i][j] <= 0;
                    timestamp[i][j] <= j;
                    for (k = 0; k < BLOCK_SIZE; k = k + 1)
                        blocks[i][j][k] <= 0;
                end
            state <= STATE_READY;
        end
        else
        begin
            state <= next_state;

            case (state)
                STATE_READY: begin
                    if (next_state == STATE_MISS)
                    begin
                        write_cnt <= 0;


                        block_offset_reg <= block_offset;
                        block_index_reg <= block_index;
                        tag_reg <= tag;
                        location_reg <= location;
                    end
                end
                STATE_MISS: begin
                    if (next_state == STATE_READY)
                    begin

                        tags[block_index_reg][location_reg] <= tag_reg;
                        valid[block_index_reg][location_reg] <= 1;
                    end


                    if (mem_read_valid)
                    begin
                        write_cnt <= write_cnt + 1;
                        blocks[block_index_reg][location_reg][write_cnt] <= mem_read;
                    end
                end
            endcase
        end
    end
endmodule