data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv
1: b"%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:18: syntax error, unexpected IDENTIFIER, expecting PACKAGE-IDENTIFIER\nmodule tlb import ariane_pkg::*; #(\n                  ^~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:20: syntax error, unexpected parameter, expecting IDENTIFIER\n      parameter int unsigned ASID_WIDTH  = 1\n      ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:21: syntax error, unexpected ')', expecting ';'\n  )(\n  ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:23: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n    input  logic                    rst_ni,    \n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:24: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n    input  logic                    flush_i,   \n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:26: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n    input  tlb_update_t             update_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:29: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n    input  logic [ASID_WIDTH-1:0]   lu_asid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:30: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n    input  logic [riscv::VLEN-1:0]  lu_vaddr_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:30: syntax error, unexpected ::, expecting ':'\n    input  logic [riscv::VLEN-1:0]  lu_vaddr_i,\n                       ^~\n                                                                                                       : ... Perhaps 'riscv' is a package which needs to be predeclared? (IEEE 1800-2017 26.3)\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:33: syntax error, unexpected input, expecting IDENTIFIER or '=' or do or final\n    input  logic [riscv::VLEN-1:0]  vaddr_to_be_flushed_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:33: syntax error, unexpected ::, expecting ':'\n    input  logic [riscv::VLEN-1:0]  vaddr_to_be_flushed_i,\n                       ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:35: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n    output logic                    lu_is_1G_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:36: syntax error, unexpected output, expecting IDENTIFIER or '=' or do or final\n    output logic                    lu_hit_o\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:42: syntax error, unexpected ::, expecting ':'\n      logic [riscv::VPN2:0]  vpn2;\n                  ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:48: syntax error, unexpected '}'\n    } [TLB_ENTRIES-1:0] tags_q, tags_n;\n    ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:52: syntax error, unexpected ::, expecting ':'\n    logic [riscv::VPN2:0] vpn2;\n                ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:58: syntax error, unexpected always_comb\n    always_comb begin : translation\n    ^~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:70: syntax error, unexpected IDENTIFIER\n        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin\n                                 ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:103: syntax error, unexpected assign\n    assign asid_to_be_flushed_is0 =  ~(|asid_to_be_flushed_i);\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:113: syntax error, unexpected IDENTIFIER\n        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin\n                                 ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:155: syntax error, unexpected always_comb\n    always_comb begin : plru_replacement\n    ^~~~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:180: syntax error, unexpected IDENTIFIER\n        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin\n                                 ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:183: syntax error, unexpected if\n            if (lu_hit[i] & lu_access_i) begin\n            ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:185: syntax error, unexpected IDENTIFIER\n                for (int unsigned lvl = 0; lvl < $clog2(TLB_ENTRIES); lvl++) begin\n                                           ^~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:209: syntax error, unexpected IDENTIFIER\n        for (int unsigned i = 0; i < TLB_ENTRIES; i += 1) begin\n                                 ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:212: syntax error, unexpected IDENTIFIER\n            en = 1'b1;\n            ^~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/tlb.sv:213: syntax error, unexpected IDENTIFIER\n            for (int unsigned lvl = 0; lvl < $clog2(TLB_ENTRIES); lvl++) begin\n                                       ^~~\n%Error: Exiting due to 27 error(s)\n"
module tlb import ariane_pkg::*; #(
      parameter int unsigned TLB_ENTRIES = 4,
      parameter int unsigned ASID_WIDTH  = 1
  )(
    input  logic                    clk_i,
    input  logic                    rst_ni,
    input  logic                    flush_i,

    input  tlb_update_t             update_i,

    input  logic                    lu_access_i,
    input  logic [ASID_WIDTH-1:0]   lu_asid_i,
    input  logic [riscv::VLEN-1:0]  lu_vaddr_i,
    output riscv::pte_t             lu_content_o,
    input  logic [ASID_WIDTH-1:0]   asid_to_be_flushed_i,
    input  logic [riscv::VLEN-1:0]  vaddr_to_be_flushed_i,
    output logic                    lu_is_2M_o,
    output logic                    lu_is_1G_o,
    output logic                    lu_hit_o
);


    struct packed {
      logic [ASID_WIDTH-1:0] asid;
      logic [riscv::VPN2:0]  vpn2;
      logic [8:0]            vpn1;
      logic [8:0]            vpn0;
      logic                  is_2M;
      logic                  is_1G;
      logic                  valid;
    } [TLB_ENTRIES-1:0] tags_q, tags_n;

    riscv::pte_t [TLB_ENTRIES-1:0] content_q, content_n;
    logic [8:0] vpn0, vpn1;
    logic [riscv::VPN2:0] vpn2;
    logic [TLB_ENTRIES-1:0] lu_hit;
    logic [TLB_ENTRIES-1:0] replace_en;



    always_comb begin : translation
        vpn0 = lu_vaddr_i[20:12];
        vpn1 = lu_vaddr_i[29:21];
        vpn2 = lu_vaddr_i[30+riscv::VPN2:30];


        lu_hit       = '{default: 0};
        lu_hit_o     = 1'b0;
        lu_content_o = '{default: 0};
        lu_is_1G_o   = 1'b0;
        lu_is_2M_o   = 1'b0;

        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin


            if (tags_q[i].valid && ((lu_asid_i == tags_q[i].asid) || content_q[i].g)  && vpn2 == tags_q[i].vpn2) begin

                if (tags_q[i].is_1G) begin
                    lu_is_1G_o = 1'b1;
                    lu_content_o = content_q[i];
                    lu_hit_o   = 1'b1;
                    lu_hit[i]  = 1'b1;

                end else if (vpn1 == tags_q[i].vpn1) begin


                    if (tags_q[i].is_2M || vpn0 == tags_q[i].vpn0) begin
                        lu_is_2M_o   = tags_q[i].is_2M;
                        lu_content_o = content_q[i];
                        lu_hit_o     = 1'b1;
                        lu_hit[i]    = 1'b1;
                    end
                end
            end
        end
    end



    logic asid_to_be_flushed_is0;
    logic vaddr_to_be_flushed_is0;
    logic  [TLB_ENTRIES-1:0] vaddr_vpn0_match;
    logic  [TLB_ENTRIES-1:0] vaddr_vpn1_match;
    logic  [TLB_ENTRIES-1:0] vaddr_vpn2_match;

    assign asid_to_be_flushed_is0 =  ~(|asid_to_be_flushed_i);
    assign vaddr_to_be_flushed_is0 = ~(|vaddr_to_be_flushed_i);




    always_comb begin : update_flush
        tags_n    = tags_q;
        content_n = content_q;

        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin

            vaddr_vpn0_match[i] = (vaddr_to_be_flushed_i[20:12] == tags_q[i].vpn0);
            vaddr_vpn1_match[i] = (vaddr_to_be_flushed_i[29:21] == tags_q[i].vpn1);
            vaddr_vpn2_match[i] = (vaddr_to_be_flushed_i[30+riscv::VPN2:30] == tags_q[i].vpn2);

            if (flush_i) begin


        				if (asid_to_be_flushed_is0 && vaddr_to_be_flushed_is0 )
                    tags_n[i].valid = 1'b0;

                else if (asid_to_be_flushed_is0 && ((vaddr_vpn0_match[i] && vaddr_vpn1_match[i] && vaddr_vpn2_match[i]) || (vaddr_vpn2_match[i] && tags_q[i].is_1G) || (vaddr_vpn1_match[i] && vaddr_vpn2_match[i] && tags_q[i].is_2M) ) && (~vaddr_to_be_flushed_is0))
                    tags_n[i].valid = 1'b0;

				        else if ((!content_q[i].g) && ((vaddr_vpn0_match[i] && vaddr_vpn1_match[i] && vaddr_vpn2_match[i]) || (vaddr_vpn2_match[i] && tags_q[i].is_1G) || (vaddr_vpn1_match[i] && vaddr_vpn2_match[i] && tags_q[i].is_2M)) && (asid_to_be_flushed_i == tags_q[i].asid) && (!vaddr_to_be_flushed_is0) && (!asid_to_be_flushed_is0))
				          	tags_n[i].valid = 1'b0;

				        else if ((!content_q[i].g) && (vaddr_to_be_flushed_is0) && (asid_to_be_flushed_i == tags_q[i].asid) && (!asid_to_be_flushed_is0))
				        	  tags_n[i].valid = 1'b0;

            end else if (update_i.valid & replace_en[i]) begin

                tags_n[i] = '{
                    asid:  update_i.asid,
                    vpn2:  update_i.vpn [18+riscv::VPN2:18],
                    vpn1:  update_i.vpn [17:9],
                    vpn0:  update_i.vpn [8:0],
                    is_1G: update_i.is_1G,
                    is_2M: update_i.is_2M,
                    valid: 1'b1
                };

                content_n[i] = update_i.content;
            end
        end
    end




    logic[2*(TLB_ENTRIES-1)-1:0] plru_tree_q, plru_tree_n;
    always_comb begin : plru_replacement
        plru_tree_n = plru_tree_q;























        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin
            automatic int unsigned idx_base, shift, new_index;

            if (lu_hit[i] & lu_access_i) begin

                for (int unsigned lvl = 0; lvl < $clog2(TLB_ENTRIES); lvl++) begin
                  idx_base = $unsigned((2**lvl)-1);

                  shift = $clog2(TLB_ENTRIES) - lvl;

                  new_index =  ~((i >> (shift-1)) & 32'b1);
                  plru_tree_n[idx_base + (i >> shift)] = new_index[0];
                end
            end
        end














        for (int unsigned i = 0; i < TLB_ENTRIES; i += 1) begin
            automatic logic en;
            automatic int unsigned idx_base, shift, new_index;
            en = 1'b1;
            for (int unsigned lvl = 0; lvl < $clog2(TLB_ENTRIES); lvl++) begin
                idx_base = $unsigned((2**lvl)-1);

                shift = $clog2(TLB_ENTRIES) - lvl;


                new_index =  (i >> (shift-1)) & 32'b1;
                if (new_index[0]) begin
                  en &= plru_tree_q[idx_base + (i>>shift)];
                end else begin
                  en &= ~plru_tree_q[idx_base + (i>>shift)];
                end
            end
            replace_en[i] = en;
        end
    end


    always_ff @(posedge clk_i or negedge rst_ni) begin
        if(~rst_ni) begin
            tags_q      <= '{default: 0};
            content_q   <= '{default: 0};
            plru_tree_q <= '{default: 0};
        end else begin
            tags_q      <= tags_n;
            content_q   <= content_n;
            plru_tree_q <= plru_tree_n;
        end
    end





    `ifndef VERILATOR

    initial begin : p_assertions
      assert ((TLB_ENTRIES % 2 == 0) && (TLB_ENTRIES > 1))
        else begin $error("TLB size must be a multiple of 2 and greater than 1"); $stop(); end
      assert (ASID_WIDTH >= 1)
        else begin $error("ASID width must be at least 1"); $stop(); end
    end


    function int countSetBits(logic[TLB_ENTRIES-1:0] vector);
      automatic int count = 0;
      foreach (vector[idx]) begin
        count += vector[idx];
      end
      return count;
    endfunction

    assert property (@(posedge clk_i)(countSetBits(lu_hit) <= 1))
      else begin $error("More then one hit in TLB!"); $stop(); end
    assert property (@(posedge clk_i)(countSetBits(replace_en) <= 1))
      else begin $error("More then one TLB entry selected for next replace!"); $stop(); end

    `endif


endmodule
module tlb import ariane_pkg::*;
 #(
      parameter int unsigned TLB_ENTRIES = 4,
      parameter int unsigned ASID_WIDTH  = 1
  )(
    input  logic                    clk_i,
    input  logic                    rst_ni,
    input  logic                    flush_i,

    input  tlb_update_t             update_i,

    input  logic                    lu_access_i,
    input  logic [ASID_WIDTH-1:0]   lu_asid_i,
    input  logic [riscv::VLEN-1:0]  lu_vaddr_i,
    output riscv::pte_t             lu_content_o,
    input  logic [ASID_WIDTH-1:0]   asid_to_be_flushed_i,
    input  logic [riscv::VLEN-1:0]  vaddr_to_be_flushed_i,
    output logic                    lu_is_2M_o,
    output logic                    lu_is_1G_o,
    output logic                    lu_hit_o
);


    struct packed {
      logic [ASID_WIDTH-1:0] asid;
      logic [riscv::VPN2:0]  vpn2;
      logic [8:0]            vpn1;
      logic [8:0]            vpn0;
      logic                  is_2M;
      logic                  is_1G;
      logic                  valid;
    } [TLB_ENTRIES-1:0] tags_q, tags_n;

    riscv::pte_t [TLB_ENTRIES-1:0] content_q, content_n;
    logic [8:0] vpn0, vpn1;
    logic [riscv::VPN2:0] vpn2;
    logic [TLB_ENTRIES-1:0] lu_hit;
    logic [TLB_ENTRIES-1:0] replace_en;



    always_comb begin : translation
        vpn0 = lu_vaddr_i[20:12];
        vpn1 = lu_vaddr_i[29:21];
        vpn2 = lu_vaddr_i[30+riscv::VPN2:30];


        lu_hit       = '{default: 0};
        lu_hit_o     = 1'b0;
        lu_content_o = '{default: 0};
        lu_is_1G_o   = 1'b0;
        lu_is_2M_o   = 1'b0;

        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin


            if (tags_q[i].valid && ((lu_asid_i == tags_q[i].asid) || content_q[i].g)  && vpn2 == tags_q[i].vpn2) begin

                if (tags_q[i].is_1G) begin
                    lu_is_1G_o = 1'b1;
                    lu_content_o = content_q[i];
                    lu_hit_o   = 1'b1;
                    lu_hit[i]  = 1'b1;

                end else if (vpn1 == tags_q[i].vpn1) begin


                    if (tags_q[i].is_2M || vpn0 == tags_q[i].vpn0) begin
                        lu_is_2M_o   = tags_q[i].is_2M;
                        lu_content_o = content_q[i];
                        lu_hit_o     = 1'b1;
                        lu_hit[i]    = 1'b1;
                    end
                end
            end
        end
    end



    logic asid_to_be_flushed_is0;
    logic vaddr_to_be_flushed_is0;
    logic  [TLB_ENTRIES-1:0] vaddr_vpn0_match;
    logic  [TLB_ENTRIES-1:0] vaddr_vpn1_match;
    logic  [TLB_ENTRIES-1:0] vaddr_vpn2_match;

    assign asid_to_be_flushed_is0 =  ~(|asid_to_be_flushed_i);
    assign vaddr_to_be_flushed_is0 = ~(|vaddr_to_be_flushed_i);




    always_comb begin : update_flush
        tags_n    = tags_q;
        content_n = content_q;

        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin

            vaddr_vpn0_match[i] = (vaddr_to_be_flushed_i[20:12] == tags_q[i].vpn0);
            vaddr_vpn1_match[i] = (vaddr_to_be_flushed_i[29:21] == tags_q[i].vpn1);
            vaddr_vpn2_match[i] = (vaddr_to_be_flushed_i[30+riscv::VPN2:30] == tags_q[i].vpn2);

            if (flush_i) begin


        				if (asid_to_be_flushed_is0 && vaddr_to_be_flushed_is0 )
                    tags_n[i].valid = 1'b0;

                else if (asid_to_be_flushed_is0 && ((vaddr_vpn0_match[i] && vaddr_vpn1_match[i] && vaddr_vpn2_match[i]) || (vaddr_vpn2_match[i] && tags_q[i].is_1G) || (vaddr_vpn1_match[i] && vaddr_vpn2_match[i] && tags_q[i].is_2M) ) && (~vaddr_to_be_flushed_is0))
                    tags_n[i].valid = 1'b0;

				        else if ((!content_q[i].g) && ((vaddr_vpn0_match[i] && vaddr_vpn1_match[i] && vaddr_vpn2_match[i]) || (vaddr_vpn2_match[i] && tags_q[i].is_1G) || (vaddr_vpn1_match[i] && vaddr_vpn2_match[i] && tags_q[i].is_2M)) && (asid_to_be_flushed_i == tags_q[i].asid) && (!vaddr_to_be_flushed_is0) && (!asid_to_be_flushed_is0))
				          	tags_n[i].valid = 1'b0;

				        else if ((!content_q[i].g) && (vaddr_to_be_flushed_is0) && (asid_to_be_flushed_i == tags_q[i].asid) && (!asid_to_be_flushed_is0))
				        	  tags_n[i].valid = 1'b0;

            end else if (update_i.valid & replace_en[i]) begin

                tags_n[i] = '{
                    asid:  update_i.asid,
                    vpn2:  update_i.vpn [18+riscv::VPN2:18],
                    vpn1:  update_i.vpn [17:9],
                    vpn0:  update_i.vpn [8:0],
                    is_1G: update_i.is_1G,
                    is_2M: update_i.is_2M,
                    valid: 1'b1
                };

                content_n[i] = update_i.content;
            end
        end
    end




    logic[2*(TLB_ENTRIES-1)-1:0] plru_tree_q, plru_tree_n;
    always_comb begin : plru_replacement
        plru_tree_n = plru_tree_q;























        for (int unsigned i = 0; i < TLB_ENTRIES; i++) begin
            automatic int unsigned idx_base, shift, new_index;

            if (lu_hit[i] & lu_access_i) begin

                for (int unsigned lvl = 0; lvl < $clog2(TLB_ENTRIES); lvl++) begin
                  idx_base = $unsigned((2**lvl)-1);

                  shift = $clog2(TLB_ENTRIES) - lvl;

                  new_index =  ~((i >> (shift-1)) & 32'b1);
                  plru_tree_n[idx_base + (i >> shift)] = new_index[0];
                end
            end
        end














        for (int unsigned i = 0; i < TLB_ENTRIES; i += 1) begin
            automatic logic en;
            automatic int unsigned idx_base, shift, new_index;
            en = 1'b1;
            for (int unsigned lvl = 0; lvl < $clog2(TLB_ENTRIES); lvl++) begin
                idx_base = $unsigned((2**lvl)-1);

                shift = $clog2(TLB_ENTRIES) - lvl;


                new_index =  (i >> (shift-1)) & 32'b1;
                if (new_index[0]) begin
                  en &= plru_tree_q[idx_base + (i>>shift)];
                end else begin
                  en &= ~plru_tree_q[idx_base + (i>>shift)];
                end
            end
            replace_en[i] = en;
        end
    end


    always_ff @(posedge clk_i or negedge rst_ni) begin
        if(~rst_ni) begin
            tags_q      <= '{default: 0};
            content_q   <= '{default: 0};
            plru_tree_q <= '{default: 0};
        end else begin
            tags_q      <= tags_n;
            content_q   <= content_n;
            plru_tree_q <= plru_tree_n;
        end
    end





    `ifndef VERILATOR

    initial begin : p_assertions
      assert ((TLB_ENTRIES % 2 == 0) && (TLB_ENTRIES > 1))
        else begin $error("TLB size must be a multiple of 2 and greater than 1"); $stop(); end
      assert (ASID_WIDTH >= 1)
        else begin $error("ASID width must be at least 1"); $stop(); end
    end


    function int countSetBits(logic[TLB_ENTRIES-1:0] vector);
      automatic int count = 0;
      foreach (vector[idx]) begin
        count += vector[idx];
      end
      return count;
    endfunction

    assert property (@(posedge clk_i)(countSetBits(lu_hit) <= 1))
      else begin $error("More then one hit in TLB!"); $stop(); end
    assert property (@(posedge clk_i)(countSetBits(replace_en) <= 1))
      else begin $error("More then one TLB entry selected for next replace!"); $stop(); end

    `endif


endmodule