data/full_repos/permissive/486588912/verilog/l1dcache.v
1: b"%Error: data/full_repos/permissive/486588912/verilog/l1dcache.v:60: Cannot find file containing module: 'l1c_dismem'\n    l1c_dismem dismem(\n    ^~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/486588912/verilog,data/full_repos/permissive/486588912/l1c_dismem\n             data/full_repos/permissive/486588912/verilog,data/full_repos/permissive/486588912/l1c_dismem.v\n             data/full_repos/permissive/486588912/verilog,data/full_repos/permissive/486588912/l1c_dismem.sv\n             l1c_dismem\n             l1c_dismem.v\n             l1c_dismem.sv\n             obj_dir/l1c_dismem\n             obj_dir/l1c_dismem.v\n             obj_dir/l1c_dismem.sv\n%Error: data/full_repos/permissive/486588912/verilog/l1dcache.v:75: Cannot find file containing module: 'dcache_bram'\n    dcache_bram cb(\n    ^~~~~~~~~~~\n%Error: data/full_repos/permissive/486588912/verilog/l1dcache.v:109: Cannot find file containing module: 'mmio_addr'\n    mmio_addr mmio_addr_1(\n    ^~~~~~~~~\n%Error: Exiting due to 3 error(s)\n"
module l1dcache(
    input sys_clk,
    input rst_n,
    

    input l1_read,
    input l1_write,
    input [31:0] l1_addr,
    input [1:0] l1_write_type,
    input [31:0] l1_write_data,

    output [31:0] l1_data_o,
    output stall,
    input  out_stall,

    input is_sync_ins,
    input [4:0] sync_type,


    output l1_mmu_req_read,
    output l1_mmu_req_write,
    output [31:0] l1_mmu_req_addr,
    output [255:0] l1_mmu_write_data,

    input mmu_l1_done,
    input [255:0] mmu_l1_read_data
);
    wire c_work = l1_read || l1_write;
    
    wire        addr_is_mmio;
    wire [16:0] addr_tag    = l1_addr[31:15];
    wire [9:0]  addr_idx    = l1_addr[14:5];
    wire [2:0]  addr_w_off  = l1_addr[4:2];
    wire [1:0]  addr_b_off  = l1_addr[1:0];
    wire        addr_h_word = l1_addr[2];


    reg write_through;
    always @(posedge sys_clk) begin
        if (!rst_n) write_through <= 1;
        else begin
            if (is_sync_ins && sync_type == 5'b10000)
                write_through <= 0;
            else if (is_sync_ins && sync_type == 5'b10001)
                write_through <= 1;
            else
                write_through <= write_through;
        end
    end



    wire [16:0] c_wd_tag        = c_flush_dirty ? 17'b0 : addr_tag;
    wire [1:0]  c_wd_st         = c_flush_dirty ? 2'b00 : (!c_hit ? 2'b01 : {!write_through, 1'b1});
    wire [18:0] cache_wd        = {c_wd_st, c_wd_tag};
    wire        cache_w;
    wire [18:0] c_o;
    l1c_dismem dismem(
        .clk(sys_clk),
        .a(addr_idx),
        .d(cache_wd),
        .we(cache_w),
        .spo(c_o));
    reg [3:0]   bram_w_type;
    reg [31:0]  bram_w_word;
    wire [63:0] bram_w_dword = {bram_w_word, bram_w_word};
    wire        bram_w_port_a;
    wire        bram_w_port_b;
    wire [31:0] bram_w_port_a_ext   = {32{bram_w_port_a}};
    wire [7:0]  bram_w_port_b_ext  = bram_w_port_b ? (addr_h_word ? {bram_w_type, 4'b0} : {4'b0, bram_w_type}) : 8'b0;
    wire [63:0] bram_dout;
    wire [255:0] bram_cl_out;
    dcache_bram cb(
        .clka(sys_clk),
        .addra(addr_idx),
        .dina(mmu_l1_read_data),
        .douta(bram_cl_out),
        .wea(bram_w_port_a_ext),

        .clkb(sys_clk),
        .addrb({addr_idx, addr_w_off[2:1]}),
        .dinb(bram_w_dword),
        .doutb(bram_dout),
        .web(bram_w_port_b_ext)
    );

    wire [31:0] bram_out        = addr_h_word ? bram_dout[63:32] : bram_dout[31:0];
    wire        c_o_dirty       = c_o[18];
    wire        c_o_valid       = c_o[17];
    wire [16:0] c_o_tag         = c_o[16:0];
    wire        c_hit           = c_o_valid && c_o_tag == addr_tag;
    wire        c_flush_dirty   = c_o_dirty && c_o_valid && c_o_tag != addr_tag;


    wire        c_write_through = c_work && c_hit && write_through && l1_write && !mmu_l1_done;
    reg         c_write_through_d0;
    always @(posedge sys_clk) c_write_through_d0 <= c_write_through;


    wire need_flush_dirty = c_flush_dirty && c_work;
    reg flush_dirty_delayed;
    always @(posedge sys_clk) flush_dirty_delayed <= need_flush_dirty;
    wire flush_dirty_set_mmu_write = flush_dirty_delayed && need_flush_dirty;



    mmio_addr mmio_addr_1(
        .addr(l1_addr),
        .is_mmio(addr_is_mmio)
    );

    wire can_read = !addr_is_mmio && c_work && c_hit && l1_read && !can_read_d0;
    reg can_read_d0;
    always @(posedge sys_clk) can_read_d0 <= can_read;
    wire read_stall = can_read && !can_read_d0;



    wire disable_write_cache_wt = write_through && c_write_through_d0;


    assign bram_w_port_a = !addr_is_mmio && c_work && !c_hit && !c_flush_dirty && mmu_l1_done;

    
    assign bram_w_port_b = !addr_is_mmio && c_work && c_hit && l1_write && !disable_write_cache_wt;


    assign cache_w = !addr_is_mmio && c_work && (c_hit && l1_write || !c_hit && mmu_l1_done) && !disable_write_cache_wt;

    
    wire   write_after_mmu_read = c_work && !addr_is_mmio && l1_write && !c_hit;


    reg        mmio_done;
    reg [31:0] mmio_data;
    always @(posedge sys_clk) begin
        if (!rst_n) begin
            mmio_done <= 0;
            mmio_data <= 32'b0;
        end else begin
            if (addr_is_mmio && (l1_read || l1_write)) begin
                if (!mmio_done) begin
                    mmio_done <= mmu_l1_done;
                    mmio_data <= mmu_l1_read_data[31:0];
                end else begin
                    if (out_stall) begin
                        mmio_done <= mmio_done;
                        mmio_data <= mmio_data;
                    end else begin
                        mmio_done <= 0;
                        mmio_data <= 32'b0;
                    end
                end
            end else begin
                mmio_done <= 0;
                mmio_data <= 32'b0;
            end
        end
    end





    assign stall                = c_work && (
                                                (!addr_is_mmio && (
                                                    !c_hit
                                                    || (c_write_through && !mmu_l1_done) 
                                                    || write_after_mmu_read
                                                    || read_stall
                                                ))
                                             || (addr_is_mmio && !mmio_done));
    assign l1_data_o            = addr_is_mmio ? mmio_data : bram_out;
    

    assign l1_mmu_req_read      = !addr_is_mmio && c_work && !c_hit && !c_flush_dirty || (addr_is_mmio && l1_read && !mmio_done);
    assign l1_mmu_req_write     = !addr_is_mmio && c_work && ((!c_hit && flush_dirty_set_mmu_write) || (c_write_through_d0)) || (addr_is_mmio && l1_write && !mmio_done);
    assign l1_mmu_req_addr      = (!addr_is_mmio && (c_flush_dirty || c_write_through_d0)) ? {c_o_tag, addr_idx, 5'b00000} : l1_addr;
    assign l1_mmu_write_data    = addr_is_mmio ? {224'b0, l1_write_data}: bram_cl_out;

    always @* begin

        casex ({l1_write_type, l1_addr[1:0]})
            4'b0000 : bram_w_type = 4'b0001;
            4'b0001 : bram_w_type = 4'b0010;
            4'b0010 : bram_w_type = 4'b0100;
            4'b0011 : bram_w_type = 4'b1000;
            4'b010x : bram_w_type = 4'b0011;
            4'b011x : bram_w_type = 4'b1100;
            4'b10xx : bram_w_type = 4'b0000;
            4'b11xx : bram_w_type = 4'b1111;
            default : bram_w_type = 4'b0000;
        endcase
        casex ({l1_write_type, l1_addr[1:0]})
            4'b0000 : bram_w_word = {24'b0, l1_write_data[7:0]};
            4'b0001 : bram_w_word = {16'b0, l1_write_data[7:0], 8'b0};
            4'b0010 : bram_w_word = {8'b0, l1_write_data[7:0], 16'b0};
            4'b0011 : bram_w_word = {l1_write_data[7:0], 24'b0};

            4'b010x : bram_w_word = {16'b0, l1_write_data[15:0]};
            4'b011x : bram_w_word = {l1_write_data[15:0], 16'b0};

            4'b10xx : bram_w_word = 32'b0;
            4'b11xx : bram_w_word = l1_write_data;
            default : bram_w_word = 32'b0;
        endcase
    end

endmodule
module l1dcache(
    input sys_clk,
    input rst_n,
    

    input l1_read,
    input l1_write,
    input [31:0] l1_addr,
    input [1:0] l1_write_type,
    input [31:0] l1_write_data,

    output [31:0] l1_data_o,
    output stall,
    input  out_stall,

    input is_sync_ins,
    input [4:0] sync_type,


    output l1_mmu_req_read,
    output l1_mmu_req_write,
    output [31:0] l1_mmu_req_addr,
    output [255:0] l1_mmu_write_data,

    input mmu_l1_done,
    input [255:0] mmu_l1_read_data
);

    wire c_work = l1_read || l1_write;
    
    wire        addr_is_mmio;
    wire [16:0] addr_tag    = l1_addr[31:15];
    wire [9:0]  addr_idx    = l1_addr[14:5];
    wire [2:0]  addr_w_off  = l1_addr[4:2];
    wire [1:0]  addr_b_off  = l1_addr[1:0];
    wire        addr_h_word = l1_addr[2];


    reg write_through;
    always @(posedge sys_clk) begin
        if (!rst_n) write_through <= 1;
        else begin
            if (is_sync_ins && sync_type == 5'b10000)
                write_through <= 0;
            else if (is_sync_ins && sync_type == 5'b10001)
                write_through <= 1;
            else
                write_through <= write_through;
        end
    end



    wire [16:0] c_wd_tag        = c_flush_dirty ? 17'b0 : addr_tag;
    wire [1:0]  c_wd_st         = c_flush_dirty ? 2'b00 : (!c_hit ? 2'b01 : {!write_through, 1'b1});
    wire [18:0] cache_wd        = {c_wd_st, c_wd_tag};
    wire        cache_w;
    wire [18:0] c_o;
    l1c_dismem dismem(
        .clk(sys_clk),
        .a(addr_idx),
        .d(cache_wd),
        .we(cache_w),
        .spo(c_o));
    reg [3:0]   bram_w_type;
    reg [31:0]  bram_w_word;
    wire [63:0] bram_w_dword = {bram_w_word, bram_w_word};
    wire        bram_w_port_a;
    wire        bram_w_port_b;
    wire [31:0] bram_w_port_a_ext   = {32{bram_w_port_a}};
    wire [7:0]  bram_w_port_b_ext  = bram_w_port_b ? (addr_h_word ? {bram_w_type, 4'b0} : {4'b0, bram_w_type}) : 8'b0;
    wire [63:0] bram_dout;
    wire [255:0] bram_cl_out;
    dcache_bram cb(
        .clka(sys_clk),
        .addra(addr_idx),
        .dina(mmu_l1_read_data),
        .douta(bram_cl_out),
        .wea(bram_w_port_a_ext),

        .clkb(sys_clk),
        .addrb({addr_idx, addr_w_off[2:1]}),
        .dinb(bram_w_dword),
        .doutb(bram_dout),
        .web(bram_w_port_b_ext)
    );

    wire [31:0] bram_out        = addr_h_word ? bram_dout[63:32] : bram_dout[31:0];
    wire        c_o_dirty       = c_o[18];
    wire        c_o_valid       = c_o[17];
    wire [16:0] c_o_tag         = c_o[16:0];
    wire        c_hit           = c_o_valid && c_o_tag == addr_tag;
    wire        c_flush_dirty   = c_o_dirty && c_o_valid && c_o_tag != addr_tag;


    wire        c_write_through = c_work && c_hit && write_through && l1_write && !mmu_l1_done;
    reg         c_write_through_d0;
    always @(posedge sys_clk) c_write_through_d0 <= c_write_through;


    wire need_flush_dirty = c_flush_dirty && c_work;
    reg flush_dirty_delayed;
    always @(posedge sys_clk) flush_dirty_delayed <= need_flush_dirty;
    wire flush_dirty_set_mmu_write = flush_dirty_delayed && need_flush_dirty;



    mmio_addr mmio_addr_1(
        .addr(l1_addr),
        .is_mmio(addr_is_mmio)
    );

    wire can_read = !addr_is_mmio && c_work && c_hit && l1_read && !can_read_d0;
    reg can_read_d0;
    always @(posedge sys_clk) can_read_d0 <= can_read;
    wire read_stall = can_read && !can_read_d0;



    wire disable_write_cache_wt = write_through && c_write_through_d0;


    assign bram_w_port_a = !addr_is_mmio && c_work && !c_hit && !c_flush_dirty && mmu_l1_done;

    
    assign bram_w_port_b = !addr_is_mmio && c_work && c_hit && l1_write && !disable_write_cache_wt;


    assign cache_w = !addr_is_mmio && c_work && (c_hit && l1_write || !c_hit && mmu_l1_done) && !disable_write_cache_wt;

    
    wire   write_after_mmu_read = c_work && !addr_is_mmio && l1_write && !c_hit;


    reg        mmio_done;
    reg [31:0] mmio_data;
    always @(posedge sys_clk) begin
        if (!rst_n) begin
            mmio_done <= 0;
            mmio_data <= 32'b0;
        end else begin
            if (addr_is_mmio && (l1_read || l1_write)) begin
                if (!mmio_done) begin
                    mmio_done <= mmu_l1_done;
                    mmio_data <= mmu_l1_read_data[31:0];
                end else begin
                    if (out_stall) begin
                        mmio_done <= mmio_done;
                        mmio_data <= mmio_data;
                    end else begin
                        mmio_done <= 0;
                        mmio_data <= 32'b0;
                    end
                end
            end else begin
                mmio_done <= 0;
                mmio_data <= 32'b0;
            end
        end
    end





    assign stall                = c_work && (
                                                (!addr_is_mmio && (
                                                    !c_hit
                                                    || (c_write_through && !mmu_l1_done) 
                                                    || write_after_mmu_read
                                                    || read_stall
                                                ))
                                             || (addr_is_mmio && !mmio_done));
    assign l1_data_o            = addr_is_mmio ? mmio_data : bram_out;
    

    assign l1_mmu_req_read      = !addr_is_mmio && c_work && !c_hit && !c_flush_dirty || (addr_is_mmio && l1_read && !mmio_done);
    assign l1_mmu_req_write     = !addr_is_mmio && c_work && ((!c_hit && flush_dirty_set_mmu_write) || (c_write_through_d0)) || (addr_is_mmio && l1_write && !mmio_done);
    assign l1_mmu_req_addr      = (!addr_is_mmio && (c_flush_dirty || c_write_through_d0)) ? {c_o_tag, addr_idx, 5'b00000} : l1_addr;
    assign l1_mmu_write_data    = addr_is_mmio ? {224'b0, l1_write_data}: bram_cl_out;

    always @* begin

        casex ({l1_write_type, l1_addr[1:0]})
            4'b0000 : bram_w_type = 4'b0001;
            4'b0001 : bram_w_type = 4'b0010;
            4'b0010 : bram_w_type = 4'b0100;
            4'b0011 : bram_w_type = 4'b1000;
            4'b010x : bram_w_type = 4'b0011;
            4'b011x : bram_w_type = 4'b1100;
            4'b10xx : bram_w_type = 4'b0000;
            4'b11xx : bram_w_type = 4'b1111;
            default : bram_w_type = 4'b0000;
        endcase
        casex ({l1_write_type, l1_addr[1:0]})
            4'b0000 : bram_w_word = {24'b0, l1_write_data[7:0]};
            4'b0001 : bram_w_word = {16'b0, l1_write_data[7:0], 8'b0};
            4'b0010 : bram_w_word = {8'b0, l1_write_data[7:0], 16'b0};
            4'b0011 : bram_w_word = {l1_write_data[7:0], 24'b0};

            4'b010x : bram_w_word = {16'b0, l1_write_data[15:0]};
            4'b011x : bram_w_word = {l1_write_data[15:0], 16'b0};

            4'b10xx : bram_w_word = 32'b0;
            4'b11xx : bram_w_word = l1_write_data;
            default : bram_w_word = 32'b0;
        endcase
    end

endmodule