//
// Generated by Bluespec Compiler, version 2018.10.beta1 (build e1df8052c, 2018-10-17)
//
//
//
//
// Ports:
// Name                         I/O  size props
// RDY_flush                      O     1 const
// lookup                         O    69
// RDY_lookup                     O     1
// RDY_insert                     O     1
// CLK                            I     1 clock
// RST_N                          I     1 reset
// lookup_asid                    I     9
// lookup_vpn                     I    20
// insert_asid                    I     9 reg
// insert_vpn                     I    20
// insert_pte                     I    32 reg
// insert_level                   I     2
// insert_pte_pa                  I    34 reg
// EN_flush                       I     1
// EN_insert                      I     1
//
// Combinational paths from inputs to outputs:
//   (lookup_asid, lookup_vpn) -> lookup
//
//

`ifdef BSV_ASSIGNMENT_DELAY
`else
  `define BSV_ASSIGNMENT_DELAY
`endif

`ifdef BSV_POSITIVE_RESET
  `define BSV_RESET_VALUE 1'b1
  `define BSV_RESET_EDGE posedge
`else
  `define BSV_RESET_VALUE 1'b0
  `define BSV_RESET_EDGE negedge
`endif

module mkTLB(CLK,
	     RST_N,

	     EN_flush,
	     RDY_flush,

	     lookup_asid,
	     lookup_vpn,
	     lookup,
	     RDY_lookup,

	     insert_asid,
	     insert_vpn,
	     insert_pte,
	     insert_level,
	     insert_pte_pa,
	     EN_insert,
	     RDY_insert);
  parameter [0 : 0] dmem_not_imem = 1'b0;
  input  CLK;
  input  RST_N;

  // action method flush
  input  EN_flush;
  output RDY_flush;

  // value method lookup
  input  [8 : 0] lookup_asid;
  input  [19 : 0] lookup_vpn;
  output [68 : 0] lookup;
  output RDY_lookup;

  // action method insert
  input  [8 : 0] insert_asid;
  input  [19 : 0] insert_vpn;
  input  [31 : 0] insert_pte;
  input  [1 : 0] insert_level;
  input  [33 : 0] insert_pte_pa;
  input  EN_insert;
  output RDY_insert;

  // signals for module outputs
  wire [68 : 0] lookup;
  wire RDY_flush, RDY_insert, RDY_lookup;

  // register rg_flushing
  reg rg_flushing;
  wire rg_flushing$D_IN, rg_flushing$EN;

  // register tlb0_valids_0
  reg tlb0_valids_0;
  wire tlb0_valids_0$D_IN, tlb0_valids_0$EN;

  // register tlb0_valids_1
  reg tlb0_valids_1;
  wire tlb0_valids_1$D_IN, tlb0_valids_1$EN;

  // register tlb0_valids_2
  reg tlb0_valids_2;
  wire tlb0_valids_2$D_IN, tlb0_valids_2$EN;

  // register tlb0_valids_3
  reg tlb0_valids_3;
  wire tlb0_valids_3$D_IN, tlb0_valids_3$EN;

  // register tlb1_valids_0
  reg tlb1_valids_0;
  wire tlb1_valids_0$D_IN, tlb1_valids_0$EN;

  // register tlb1_valids_1
  reg tlb1_valids_1;
  wire tlb1_valids_1$D_IN, tlb1_valids_1$EN;

  // register tlb1_valids_2
  reg tlb1_valids_2;
  wire tlb1_valids_2$D_IN, tlb1_valids_2$EN;

  // register tlb1_valids_3
  reg tlb1_valids_3;
  wire tlb1_valids_3$D_IN, tlb1_valids_3$EN;

  // ports of submodule tlb0_entries
  wire [102 : 0] tlb0_entries$D_IN, tlb0_entries$D_OUT_1;
  wire [1 : 0] tlb0_entries$ADDR_1,
	       tlb0_entries$ADDR_2,
	       tlb0_entries$ADDR_3,
	       tlb0_entries$ADDR_4,
	       tlb0_entries$ADDR_5,
	       tlb0_entries$ADDR_IN;
  wire tlb0_entries$WE;

  // ports of submodule tlb1_entries
  wire [92 : 0] tlb1_entries$D_IN, tlb1_entries$D_OUT_1;
  wire [1 : 0] tlb1_entries$ADDR_1,
	       tlb1_entries$ADDR_2,
	       tlb1_entries$ADDR_3,
	       tlb1_entries$ADDR_4,
	       tlb1_entries$ADDR_5,
	       tlb1_entries$ADDR_IN;
  wire tlb1_entries$WE;

  // rule scheduling signals
  wire CAN_FIRE_RL_rl_initialize,
       CAN_FIRE_flush,
       CAN_FIRE_insert,
       WILL_FIRE_RL_rl_initialize,
       WILL_FIRE_flush,
       WILL_FIRE_insert;

  // inputs to muxes for submodule ports
  wire MUX_tlb0_valids_0$write_1__SEL_1,
       MUX_tlb0_valids_1$write_1__SEL_1,
       MUX_tlb0_valids_2$write_1__SEL_1,
       MUX_tlb0_valids_3$write_1__SEL_1,
       MUX_tlb1_valids_0$write_1__SEL_1,
       MUX_tlb1_valids_1$write_1__SEL_1,
       MUX_tlb1_valids_2$write_1__SEL_1,
       MUX_tlb1_valids_3$write_1__SEL_1;

  // remaining internal signals
  reg SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d30,
      SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_valid_ETC___d8;
  wire [67 : 0] IF_NOT_SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb_ETC___d62;
  wire [27 : 0] tag__h2330, tag__h2574;
  wire [17 : 0] tag__h2210, tag__h2585;
  wire NOT_SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_v_ETC___d23,
       SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d41,
       tlb0_entries_sub_lookup_vpn_BITS_1_TO_0_9_1_BI_ETC___d33,
       tlb0_entries_sub_lookup_vpn_BITS_1_TO_0_9_1_BI_ETC___d40,
       tlb1_entries_sub_lookup_vpn_BITS_11_TO_10_0_BI_ETC___d12,
       tlb1_entries_sub_lookup_vpn_BITS_11_TO_10_0_BI_ETC___d21;

  // action method flush
  assign RDY_flush = 1'd1 ;
  assign CAN_FIRE_flush = 1'd1 ;
  assign WILL_FIRE_flush = EN_flush ;

  // value method lookup
  assign lookup =
	     { NOT_SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_v_ETC___d23 &&
	       SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d41 ||
	       SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_valid_ETC___d8 &&
	       (tlb1_entries_sub_lookup_vpn_BITS_11_TO_10_0_BI_ETC___d12 ||
		tlb1_entries$D_OUT_1[39]) &&
	       tlb1_entries_sub_lookup_vpn_BITS_11_TO_10_0_BI_ETC___d21 &&
	       (!SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d30 ||
		!tlb0_entries_sub_lookup_vpn_BITS_1_TO_0_9_1_BI_ETC___d33 &&
		!tlb0_entries$D_OUT_1[39] ||
		!tlb0_entries_sub_lookup_vpn_BITS_1_TO_0_9_1_BI_ETC___d40),
	       IF_NOT_SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb_ETC___d62 } ;
  assign RDY_lookup = !rg_flushing ;

  // action method insert
  assign RDY_insert = !rg_flushing ;
  assign CAN_FIRE_insert = !rg_flushing ;
  assign WILL_FIRE_insert = EN_insert ;

  // submodule tlb0_entries
  RegFile #(.addr_width(32'd2),
	    .data_width(32'd103),
	    .lo(2'h0),
	    .hi(2'd3)) tlb0_entries(.CLK(CLK),
				    .ADDR_1(tlb0_entries$ADDR_1),
				    .ADDR_2(tlb0_entries$ADDR_2),
				    .ADDR_3(tlb0_entries$ADDR_3),
				    .ADDR_4(tlb0_entries$ADDR_4),
				    .ADDR_5(tlb0_entries$ADDR_5),
				    .ADDR_IN(tlb0_entries$ADDR_IN),
				    .D_IN(tlb0_entries$D_IN),
				    .WE(tlb0_entries$WE),
				    .D_OUT_1(tlb0_entries$D_OUT_1),
				    .D_OUT_2(),
				    .D_OUT_3(),
				    .D_OUT_4(),
				    .D_OUT_5());

  // submodule tlb1_entries
  RegFile #(.addr_width(32'd2),
	    .data_width(32'd93),
	    .lo(2'h0),
	    .hi(2'd3)) tlb1_entries(.CLK(CLK),
				    .ADDR_1(tlb1_entries$ADDR_1),
				    .ADDR_2(tlb1_entries$ADDR_2),
				    .ADDR_3(tlb1_entries$ADDR_3),
				    .ADDR_4(tlb1_entries$ADDR_4),
				    .ADDR_5(tlb1_entries$ADDR_5),
				    .ADDR_IN(tlb1_entries$ADDR_IN),
				    .D_IN(tlb1_entries$D_IN),
				    .WE(tlb1_entries$WE),
				    .D_OUT_1(tlb1_entries$D_OUT_1),
				    .D_OUT_2(),
				    .D_OUT_3(),
				    .D_OUT_4(),
				    .D_OUT_5());

  // rule RL_rl_initialize
  assign CAN_FIRE_RL_rl_initialize = rg_flushing ;
  assign WILL_FIRE_RL_rl_initialize = rg_flushing ;

  // inputs to muxes for submodule ports
  assign MUX_tlb0_valids_0$write_1__SEL_1 =
	     EN_insert && insert_vpn[1:0] == 2'd0 && insert_level == 2'd0 ;
  assign MUX_tlb0_valids_1$write_1__SEL_1 =
	     EN_insert && insert_vpn[1:0] == 2'd1 && insert_level == 2'd0 ;
  assign MUX_tlb0_valids_2$write_1__SEL_1 =
	     EN_insert && insert_vpn[1:0] == 2'd2 && insert_level == 2'd0 ;
  assign MUX_tlb0_valids_3$write_1__SEL_1 =
	     EN_insert && insert_vpn[1:0] == 2'd3 && insert_level == 2'd0 ;
  assign MUX_tlb1_valids_0$write_1__SEL_1 =
	     EN_insert && insert_vpn[11:10] == 2'd0 && insert_level == 2'd1 ;
  assign MUX_tlb1_valids_1$write_1__SEL_1 =
	     EN_insert && insert_vpn[11:10] == 2'd1 && insert_level == 2'd1 ;
  assign MUX_tlb1_valids_2$write_1__SEL_1 =
	     EN_insert && insert_vpn[11:10] == 2'd2 && insert_level == 2'd1 ;
  assign MUX_tlb1_valids_3$write_1__SEL_1 =
	     EN_insert && insert_vpn[11:10] == 2'd3 && insert_level == 2'd1 ;

  // register rg_flushing
  assign rg_flushing$D_IN = EN_flush ;
  assign rg_flushing$EN = rg_flushing || EN_flush ;

  // register tlb0_valids_0
  assign tlb0_valids_0$D_IN = MUX_tlb0_valids_0$write_1__SEL_1 ;
  assign tlb0_valids_0$EN =
	     EN_insert && insert_vpn[1:0] == 2'd0 && insert_level == 2'd0 ||
	     rg_flushing ;

  // register tlb0_valids_1
  assign tlb0_valids_1$D_IN = MUX_tlb0_valids_1$write_1__SEL_1 ;
  assign tlb0_valids_1$EN =
	     EN_insert && insert_vpn[1:0] == 2'd1 && insert_level == 2'd0 ||
	     rg_flushing ;

  // register tlb0_valids_2
  assign tlb0_valids_2$D_IN = MUX_tlb0_valids_2$write_1__SEL_1 ;
  assign tlb0_valids_2$EN =
	     EN_insert && insert_vpn[1:0] == 2'd2 && insert_level == 2'd0 ||
	     rg_flushing ;

  // register tlb0_valids_3
  assign tlb0_valids_3$D_IN = MUX_tlb0_valids_3$write_1__SEL_1 ;
  assign tlb0_valids_3$EN =
	     EN_insert && insert_vpn[1:0] == 2'd3 && insert_level == 2'd0 ||
	     rg_flushing ;

  // register tlb1_valids_0
  assign tlb1_valids_0$D_IN = MUX_tlb1_valids_0$write_1__SEL_1 ;
  assign tlb1_valids_0$EN =
	     EN_insert && insert_vpn[11:10] == 2'd0 && insert_level == 2'd1 ||
	     rg_flushing ;

  // register tlb1_valids_1
  assign tlb1_valids_1$D_IN = MUX_tlb1_valids_1$write_1__SEL_1 ;
  assign tlb1_valids_1$EN =
	     EN_insert && insert_vpn[11:10] == 2'd1 && insert_level == 2'd1 ||
	     rg_flushing ;

  // register tlb1_valids_2
  assign tlb1_valids_2$D_IN = MUX_tlb1_valids_2$write_1__SEL_1 ;
  assign tlb1_valids_2$EN =
	     EN_insert && insert_vpn[11:10] == 2'd2 && insert_level == 2'd1 ||
	     rg_flushing ;

  // register tlb1_valids_3
  assign tlb1_valids_3$D_IN = MUX_tlb1_valids_3$write_1__SEL_1 ;
  assign tlb1_valids_3$EN =
	     EN_insert && insert_vpn[11:10] == 2'd3 && insert_level == 2'd1 ||
	     rg_flushing ;

  // submodule tlb0_entries
  assign tlb0_entries$ADDR_1 = lookup_vpn[1:0] ;
  assign tlb0_entries$ADDR_2 = 2'h0 ;
  assign tlb0_entries$ADDR_3 = 2'h0 ;
  assign tlb0_entries$ADDR_4 = 2'h0 ;
  assign tlb0_entries$ADDR_5 = 2'h0 ;
  assign tlb0_entries$ADDR_IN = insert_vpn[1:0] ;
  assign tlb0_entries$D_IN =
	     { insert_asid, tag__h2574, insert_pte, insert_pte_pa } ;
  assign tlb0_entries$WE = EN_insert && insert_level == 2'd0 ;

  // submodule tlb1_entries
  assign tlb1_entries$ADDR_1 = lookup_vpn[11:10] ;
  assign tlb1_entries$ADDR_2 = 2'h0 ;
  assign tlb1_entries$ADDR_3 = 2'h0 ;
  assign tlb1_entries$ADDR_4 = 2'h0 ;
  assign tlb1_entries$ADDR_5 = 2'h0 ;
  assign tlb1_entries$ADDR_IN = insert_vpn[11:10] ;
  assign tlb1_entries$D_IN =
	     { insert_asid, tag__h2585, insert_pte, insert_pte_pa } ;
  assign tlb1_entries$WE = EN_insert && insert_level == 2'd1 ;

  // remaining internal signals
  assign IF_NOT_SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb_ETC___d62 =
	     (NOT_SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_v_ETC___d23 &&
	      SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d41) ?
	       { tlb0_entries$D_OUT_1[65:34],
		 2'd0,
		 tlb0_entries$D_OUT_1[33:0] } :
	       { tlb1_entries$D_OUT_1[65:34],
		 2'd1,
		 tlb1_entries$D_OUT_1[33:0] } ;
  assign NOT_SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_v_ETC___d23 =
	     !SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_valid_ETC___d8 ||
	     !tlb1_entries_sub_lookup_vpn_BITS_11_TO_10_0_BI_ETC___d12 &&
	     !tlb1_entries$D_OUT_1[39] ||
	     !tlb1_entries_sub_lookup_vpn_BITS_11_TO_10_0_BI_ETC___d21 ;
  assign SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d41 =
	     SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d30 &&
	     (tlb0_entries_sub_lookup_vpn_BITS_1_TO_0_9_1_BI_ETC___d33 ||
	      tlb0_entries$D_OUT_1[39]) &&
	     tlb0_entries_sub_lookup_vpn_BITS_1_TO_0_9_1_BI_ETC___d40 ;
  assign tag__h2210 = { 10'd0, lookup_vpn[19:12] } ;
  assign tag__h2330 = { 10'd0, lookup_vpn[19:2] } ;
  assign tag__h2574 = { 10'd0, insert_vpn[19:2] } ;
  assign tag__h2585 = { 10'd0, insert_vpn[19:12] } ;
  assign tlb0_entries_sub_lookup_vpn_BITS_1_TO_0_9_1_BI_ETC___d33 =
	     tlb0_entries$D_OUT_1[102:94] == lookup_asid ;
  assign tlb0_entries_sub_lookup_vpn_BITS_1_TO_0_9_1_BI_ETC___d40 =
	     tlb0_entries$D_OUT_1[93:66] == tag__h2330 ;
  assign tlb1_entries_sub_lookup_vpn_BITS_11_TO_10_0_BI_ETC___d12 =
	     tlb1_entries$D_OUT_1[92:84] == lookup_asid ;
  assign tlb1_entries_sub_lookup_vpn_BITS_11_TO_10_0_BI_ETC___d21 =
	     tlb1_entries$D_OUT_1[83:66] == tag__h2210 ;
  always@(lookup_vpn or
	  tlb1_valids_0 or tlb1_valids_1 or tlb1_valids_2 or tlb1_valids_3)
  begin
    case (lookup_vpn[11:10])
      2'd0:
	  SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_valid_ETC___d8 =
	      tlb1_valids_0;
      2'd1:
	  SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_valid_ETC___d8 =
	      tlb1_valids_1;
      2'd2:
	  SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_valid_ETC___d8 =
	      tlb1_valids_2;
      2'd3:
	  SEL_ARR_tlb1_valids_0_tlb1_valids_1_tlb1_valid_ETC___d8 =
	      tlb1_valids_3;
    endcase
  end
  always@(lookup_vpn or
	  tlb0_valids_0 or tlb0_valids_1 or tlb0_valids_2 or tlb0_valids_3)
  begin
    case (lookup_vpn[1:0])
      2'd0:
	  SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d30 =
	      tlb0_valids_0;
      2'd1:
	  SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d30 =
	      tlb0_valids_1;
      2'd2:
	  SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d30 =
	      tlb0_valids_2;
      2'd3:
	  SEL_ARR_tlb0_valids_0_4_tlb0_valids_1_5_tlb0_v_ETC___d30 =
	      tlb0_valids_3;
    endcase
  end

  // handling of inlined registers

  always@(posedge CLK)
  begin
    if (RST_N == `BSV_RESET_VALUE)
      begin
        rg_flushing <= `BSV_ASSIGNMENT_DELAY 1'd1;
      end
    else
      begin
        if (rg_flushing$EN)
	  rg_flushing <= `BSV_ASSIGNMENT_DELAY rg_flushing$D_IN;
      end
    if (tlb0_valids_0$EN)
      tlb0_valids_0 <= `BSV_ASSIGNMENT_DELAY tlb0_valids_0$D_IN;
    if (tlb0_valids_1$EN)
      tlb0_valids_1 <= `BSV_ASSIGNMENT_DELAY tlb0_valids_1$D_IN;
    if (tlb0_valids_2$EN)
      tlb0_valids_2 <= `BSV_ASSIGNMENT_DELAY tlb0_valids_2$D_IN;
    if (tlb0_valids_3$EN)
      tlb0_valids_3 <= `BSV_ASSIGNMENT_DELAY tlb0_valids_3$D_IN;
    if (tlb1_valids_0$EN)
      tlb1_valids_0 <= `BSV_ASSIGNMENT_DELAY tlb1_valids_0$D_IN;
    if (tlb1_valids_1$EN)
      tlb1_valids_1 <= `BSV_ASSIGNMENT_DELAY tlb1_valids_1$D_IN;
    if (tlb1_valids_2$EN)
      tlb1_valids_2 <= `BSV_ASSIGNMENT_DELAY tlb1_valids_2$D_IN;
    if (tlb1_valids_3$EN)
      tlb1_valids_3 <= `BSV_ASSIGNMENT_DELAY tlb1_valids_3$D_IN;
  end

  // synopsys translate_off
  `ifdef BSV_NO_INITIAL_BLOCKS
  `else // not BSV_NO_INITIAL_BLOCKS
  initial
  begin
    rg_flushing = 1'h0;
    tlb0_valids_0 = 1'h0;
    tlb0_valids_1 = 1'h0;
    tlb0_valids_2 = 1'h0;
    tlb0_valids_3 = 1'h0;
    tlb1_valids_0 = 1'h0;
    tlb1_valids_1 = 1'h0;
    tlb1_valids_2 = 1'h0;
    tlb1_valids_3 = 1'h0;
  end
  `endif // BSV_NO_INITIAL_BLOCKS
  // synopsys translate_on
endmodule  // mkTLB

