{%- for thread in threads %}
// Thread "{{ thread.name }}" BEGIN
{% for memory in thread.memories %}
{%- if memory.scattergather %}
// Scatter/Gather ON
{%- endif %}
module DMAC_MEMORY_{{ thread.name }}_{{ memory.name }} #
  (
   //----------------------------------------------------------------------------
   // User Parameter
   //----------------------------------------------------------------------------
   parameter W_A = {{ memory.addrwidth }}, // word addressing
   parameter W_D = {{ memory.datawidth }}, // power of 2
   parameter W_EXT_A = {{ ext_addrwidth }}, // byte addressing
   parameter W_EXT_D = {{ memory.ext_datawidth }}, // power of 2
   parameter ADDRMASK_WIDTH = {{ int(log(memory.ext_datawidth/8, 2)) }}, //log(W_D/8)

   parameter NUM_RANKS = {{ memory.numranks }}, // power of 2
   parameter LOG_NUM_RANKS = {{ memory.lognumranks }},
   parameter NUM_PAGES = {{ memory.numpages }}, // power of 2
   parameter LOG_NUM_PAGES = {{ memory.lognumpages }},

   parameter W_BOUNDARY_A = 12, // for 4KB boundary limitation of AXI
   parameter W_BLEN = {{ ext_burstlen_width }}, //log(MAX_BURST_LEN)
   parameter MAX_BURST_LEN = {{ ext_burstlength }}, // burst length

   parameter CMD_FIFO_ADDR_WIDTH = 4, // Command Buffer
   parameter ASYNC = 1, // control-thread uses a different clock
   parameter SUPPORTS_WRITE = 1
   )
  (

   //----------------------------------------------------------------------------
   // Bus Clock
   //----------------------------------------------------------------------------
   input wire ACLK,
   input wire ARESETN,

   //---------------------------------------------------------------------------
   // User-logic BRAM
   //---------------------------------------------------------------------------
{%- for bank in range(memory.length) %}
   output wire [W_A-1:0]    core_addr_{{ bank }}, // word addressing
   output wire              core_read_enable_{{ bank }},
   input wire [W_D-1:0]     core_read_data_{{ bank }},
   output wire              core_write_enable_{{ bank }}, 
   output wire [W_D-1:0]    core_write_data_{{ bank }},
{% endfor %}

   //---------------------------------------------------------------------------
   // DMA Request from Control Thread
   //---------------------------------------------------------------------------
   input wire               req_clk,
   input wire               req_rst,
   input wire [W_EXT_A-1:0] req_ext_addr, // byte addressing
   input wire [W_EXT_A-1:0] req_core_addr, // word addressing
   input wire               req_read_enable,
   input wire               req_write_enable,
   input wire [W_EXT_A:0]   req_word_size, // word
   output wire              req_ready,
   output wire              req_busy,
   
   //----------------------------------------------------------------------------
   // Bus Interface
   //----------------------------------------------------------------------------
   // Write Address
   output reg                awvalid,
   output reg [W_EXT_A-1:0]  awaddr,
   output reg [W_BLEN-1:0]   awlen,
   input wire                awready,
  
   // Write Data
   output wire               wvalid,
   output wire [W_EXT_D-1:0] wdata,
   output wire               wlast,
   input wire                wready,

   // Write Response
   input wire                bvalid,
   output wire               bready,
   
   // Read Address
   output reg                arvalid,
   output reg [W_EXT_A-1:0]  araddr,
   output reg [W_BLEN-1:0]   arlen,
   input wire                arready,

   // Read Data
   input wire                rvalid,
   input wire [W_EXT_D-1:0]  rdata,
   input wire                rlast,
   output wire               rready
   ); 

  //----------------------------------------------------------------------------
  // Reset logic
  //----------------------------------------------------------------------------
  reg aresetn_r;
  reg aresetn_rr;
  reg aresetn_rrr;

  always @(posedge ACLK) begin
    aresetn_r <= ARESETN;
    aresetn_rr <= aresetn_r;
    aresetn_rrr <= aresetn_rr;
  end
  
  //----------------------------------------------------------------------------
  // mode
  //----------------------------------------------------------------------------
  reg read_offchip_busy;
  reg write_offchip_busy;

  //----------------------------------------------------------------------------
  // Request Queue
  //----------------------------------------------------------------------------
  // newest command (clock: req_clk)
  wire [W_EXT_A-1:0] req_tail_ext_addr;
  wire [W_EXT_A-1:0] req_tail_core_addr;
  wire               req_tail_read_enable;
  wire               req_tail_write_enable;
  wire [W_EXT_A:0]   req_tail_word_size;
  
  // oldest command (clock: ACLK)
  wire [W_EXT_A-1:0] req_head_ext_addr;
  wire [W_EXT_A-1:0] req_head_core_addr;
  wire               req_head_read_enable;
  wire               req_head_write_enable;
  wire [W_EXT_A:0]   req_head_word_size;

  // clock: req_clk
  wire req_enq;
  wire req_full;
  wire req_almost_full;

  // clock: ACLK
  wire req_deq;
  wire req_empty;
  wire req_almost_empty;

  //----------------------------------------------------------------------------
  // Issued Queue
  //----------------------------------------------------------------------------
  // newest command
  wire [W_EXT_A-1:0] issued_tail_core_addr;
  wire               issued_tail_read_enable;
  wire               issued_tail_write_enable;
  wire               issued_tail_burst_trunc;
  wire [W_EXT_A:0]   issued_tail_word_size;
  
  // oldest command
  wire [W_EXT_A-1:0] issued_head_core_addr;
  wire               issued_head_read_enable;
  wire               issued_head_write_enable;
  wire               issued_head_burst_trunc;
  wire [W_EXT_A:0]   issued_head_word_size;

  reg  issued_enq_condition;
  wire issued_enq;
  wire issued_full;
  wire issued_almost_full;

  wire issued_deq;
  wire issued_empty;
  wire issued_almost_empty;
  reg d_issued_deq;

  //------------------------------------------------------------------------------
  // Burst size management
  //------------------------------------------------------------------------------
  reg [2:0] req_state;
  reg [W_EXT_A-1:0] d_req_head_ext_addr;
  reg [W_EXT_A-1:0] d_req_head_core_addr;
  reg [W_EXT_A:0]   d_req_head_word_size;
  reg d_req_head_read_enable;
  reg d_req_head_write_enable;
  reg [W_EXT_A:0] rest_for_boundary;
  reg [W_EXT_A:0] size_cap;
  reg burst_trunc;
  wire [W_EXT_A:0] extended_req_head_word_size;
  
  //------------------------------------------------------------------------------
  reg local_busy_cdc_from; // ACLK
  reg req_busy_reg_cdc_to; // req_clk

  always @(posedge ACLK) begin // clock: ACLK
    local_busy_cdc_from <= read_offchip_busy || write_offchip_busy || !req_empty || !issued_empty || d_issued_deq || (req_state > 0);
  end
  
  always @(posedge req_clk) begin // clock: req_clk
    req_busy_reg_cdc_to <= local_busy_cdc_from;
  end
  
  generate if(ASYNC) begin
    assign req_busy = req_busy_reg_cdc_to; // clock: req_clk
  end else begin
    assign req_busy = local_busy_cdc_from;
  end endgenerate
  
  //----------------------------------------------------------------------------
  assign req_ready = !req_almost_full; // clock: req_clk

  assign req_enq = req_read_enable || req_write_enable;
  assign req_tail_ext_addr = req_ext_addr;
  assign req_tail_core_addr = req_core_addr;
  assign req_tail_read_enable = req_read_enable;
  assign req_tail_write_enable = req_write_enable;
  assign req_tail_word_size = req_word_size;
  
  dmac_memory_cmd_queue #
   (
    .W_EXT_A(W_EXT_A),
    .FIFO_ADDR_WIDTH(CMD_FIFO_ADDR_WIDTH),
    .ASYNC(ASYNC)
   )
  inst_cmd_queue
   (
    .tail_clk(req_clk),
    .tail_rst(req_rst),
    
    .head_clk(ACLK),
    .head_rst(~ARESETN),

    .tail_ext_addr(req_tail_ext_addr),
    .tail_core_addr(req_tail_core_addr),
    .tail_read_enable(req_tail_read_enable),
    .tail_write_enable(req_tail_write_enable),
    .tail_word_size(req_tail_word_size),

    .head_ext_addr(req_head_ext_addr),
    .head_core_addr(req_head_core_addr),
    .head_read_enable(req_head_read_enable),
    .head_write_enable(req_head_write_enable),
    .head_word_size(req_head_word_size),

    .enq(req_enq),
    .full(req_full),
    .almost_full(req_almost_full),

    .deq(req_deq),
    .empty(req_empty),
    .almost_empty(req_almost_empty)
   );
  
  //----------------------------------------------------------------------------
  assign issued_tail_core_addr = d_req_head_core_addr;
  assign issued_tail_read_enable = awvalid;
  assign issued_tail_write_enable = arvalid;
  assign issued_tail_burst_trunc = burst_trunc;
  assign issued_tail_word_size = arlen + 1;
  //assign issued_enq = (req_state == 3) && ((arvalid && arready) || (awvalid && awready));
  assign issued_enq = (req_state == 3) && issued_enq_condition;
  
  dmac_memory_issued_cmd_queue #
   (
    .W_EXT_A(W_EXT_A),
    .FIFO_ADDR_WIDTH(CMD_FIFO_ADDR_WIDTH)
   )
  inst_issued_cmd_queue
   (
    .clk(ACLK),
    .rst(~ARESETN),

    .tail_core_addr(issued_tail_core_addr),
    .tail_read_enable(issued_tail_read_enable),
    .tail_write_enable(issued_tail_write_enable),
    .tail_burst_trunc(issued_tail_burst_trunc),
    .tail_word_size(issued_tail_word_size),

    .head_core_addr(issued_head_core_addr),
    .head_read_enable(issued_head_read_enable),
    .head_write_enable(issued_head_write_enable),
    .head_burst_trunc(issued_head_burst_trunc),
    .head_word_size(issued_head_word_size),

    .enq(issued_enq),
    .full(issued_full),
    .almost_full(issued_almost_full),

    .deq(issued_deq),
    .empty(issued_empty),
    .almost_empty(issued_almost_empty)
   );

  //----------------------------------------------------------------------------
  // Command
  //----------------------------------------------------------------------------
  function [W_EXT_A-1:0] addrmask;
    input [W_EXT_A-1:0] in;
    addrmask = { in[W_EXT_A-1:ADDRMASK_WIDTH], {ADDRMASK_WIDTH{1'b0}} };
  endfunction

  function [W_EXT_A-1:0] get_rest_for_boundary;
    input [W_EXT_A-1:0] addr;
    get_rest_for_boundary = (1 << (W_BOUNDARY_A-ADDRMASK_WIDTH)) - 
                            {1'b0, addr[W_BOUNDARY_A-1:ADDRMASK_WIDTH]};
  endfunction

  assign req_deq = !req_empty && !issued_full && req_state == 0;

{%- if (log(memory.numranks,2) % 1.0) == 0.0 %}
  assign extended_req_head_word_size = req_head_word_size << LOG_NUM_RANKS;
{%- else %}
  assign extended_req_head_word_size = 
    (req_head_word_size << (LOG_NUM_RANKS-1)) +
 {%- for rank in range(memory.numranks - 2**(memory.lognumranks-1)) %}
    req_head_word_size {%- if loop.index < memory.numranks - 2**(memory.lognumranks-1) %} + {% endif -%}{% endfor %};
{%- endif %}

  always @(posedge ACLK) begin
    if(aresetn_rrr == 0) begin
      arvalid <= 0;
      araddr <= 0;
      arlen <= 0;
      awvalid <= 0;
      awaddr <= 0;
      awlen <= 0;
      d_req_head_ext_addr <= 0;
      d_req_head_core_addr <= 0;
      d_req_head_read_enable <= 0;
      d_req_head_write_enable <= 0;
      d_req_head_word_size <= 0;
      rest_for_boundary <= 0;
      size_cap <= 0;
      burst_trunc <= 0;
      req_state <= 0;
      issued_enq_condition <= 0;
    end else begin
      issued_enq_condition <= 0;
      case(req_state)
        0: begin // Init
          arvalid <= 0;
          awvalid <= 0;
          burst_trunc <= 0;
          if(req_deq) begin
            req_state <= 1;
          end
        end
        1: begin // Boundary check
          arvalid <= 0;
          awvalid <= 0;
          d_req_head_ext_addr <= addrmask(req_head_ext_addr);
          d_req_head_core_addr <= req_head_core_addr;
          d_req_head_read_enable <= req_head_read_enable;
          d_req_head_write_enable <= req_head_write_enable;
          d_req_head_word_size <= extended_req_head_word_size;
          rest_for_boundary <= get_rest_for_boundary(req_head_ext_addr);
          size_cap <= (extended_req_head_word_size <= MAX_BURST_LEN)? extended_req_head_word_size : MAX_BURST_LEN;
          if(extended_req_head_word_size == 0) req_state <= 0;
          else req_state <= 2;
        end
        2: begin // Issue
          arvalid <= d_req_head_write_enable; // Off-chip -> BRAM 
          araddr <= d_req_head_ext_addr;
          arlen <= (size_cap <= rest_for_boundary)? size_cap -1 : rest_for_boundary -1;
          awvalid <= d_req_head_read_enable; // BRAM -> Off-chip
          awaddr <= d_req_head_ext_addr;
          awlen <= (size_cap <= rest_for_boundary)? size_cap -1 : rest_for_boundary -1;
          req_state <= 3;
          issued_enq_condition <= 1;
        end
        3: begin // Wait
          if((arvalid && arready) || (awvalid && awready)) begin
            arvalid <= 0;
            awvalid <= 0;
            d_req_head_word_size <= d_req_head_word_size - arlen - 1;
            d_req_head_ext_addr <= araddr + ((arlen + 1) << ADDRMASK_WIDTH);
            if(arlen + 1 == d_req_head_word_size) req_state <= 0;
            else req_state <= 4;
          end
        end
        4: begin // Boundary check
          arvalid <= 0;
          awvalid <= 0;
          rest_for_boundary <= get_rest_for_boundary(d_req_head_ext_addr);
          size_cap <= (d_req_head_word_size <= MAX_BURST_LEN)? d_req_head_word_size : MAX_BURST_LEN;
          burst_trunc <= 1;
          req_state <= 2;
        end
      endcase
    end
  end  

  //----------------------------------------------------------------------------
  // Data
  //----------------------------------------------------------------------------
  reg [W_EXT_A:0] read_count;
  reg [W_EXT_A:0] write_count;

  reg [W_A-1:0] cur_core_addr;
  
  reg [LOG_NUM_RANKS:0] cur_rank;
  reg [LOG_NUM_RANKS:0] d_cur_rank;

{%- if not memory.scattergather %}
  reg [LOG_NUM_PAGES:0] cur_page;
  reg [LOG_NUM_PAGES:0] d_cur_page;
{%- endif %}

  wire core_read_active;
  reg d_core_read_active;

{%- for bank in range(memory.length) %}
  wire bank_write_active_{{ bank }};
  wire bank_read_active_{{ bank }};
{%- endfor %}

{%- for bank in range(memory.length) %}
  reg [W_D-1:0] core_write_data_buf_{{ bank }};
{% endfor %}

  reg d_wvalid;
  reg d_wready;
  reg [W_EXT_D-1:0] d_wdata;
  wire [W_EXT_D-1:0] next_wdata;

  assign issued_deq = !issued_empty && !d_issued_deq && !read_offchip_busy && !write_offchip_busy;

  always @(posedge ACLK) begin
    if(aresetn_rrr == 0) begin
      d_issued_deq <= 0;
      d_core_read_active <= 0;
      d_wvalid <= 0;
      d_wready <= 0;
      d_wdata <= 0;
    end else begin
      d_issued_deq <= issued_deq;
      d_core_read_active <= core_read_active;
      d_wvalid <= wvalid;
      d_wready <= wready;
      d_wdata <= wdata;
    end
  end

  assign rready = read_offchip_busy;
  assign bready = SUPPORTS_WRITE; // always accepting write response
  assign core_read_active = write_offchip_busy && (!wvalid || wready) && write_count > 0;
{%- for bank in range(memory.length) %}
{%- if memory.scattergather %}
 {%- if memory.datawidth <= memory.ext_datawidth %}
  assign bank_write_active_{{ bank }} = (cur_rank == {{ int(bank * memory.datawidth / memory.ext_datawidth) }});
 {%- else %}
  assign bank_write_active_{{ bank }} = (cur_rank == {{ int((bank+1) * memory.datawidth / memory.ext_datawidth) -1 }});
 {%- endif %}
  assign bank_read_active_{{ bank }} = (cur_rank == {{ int(bank * memory.datawidth / memory.ext_datawidth) }});
{%- else %}
  assign bank_write_active_{{ bank }} = (cur_rank == {{ memory.numranks -1 }} && (cur_page == {{ bank }}));
  assign bank_read_active_{{ bank }} = (cur_rank == 0 && (cur_page == {{ bank }}));
{%- endif %}
{%- endfor %}

{%- for bank in range(memory.length) %}
  assign core_read_enable_{{ bank }} = (write_offchip_busy && core_read_active)? bank_read_active_{{ bank }}:0;
  assign core_write_enable_{{ bank }} = (read_offchip_busy && rvalid)? bank_write_active_{{ bank }}:0;
  assign core_addr_{{ bank }} = cur_core_addr;
 {%- if memory.scattergather %}
  {%- if memory.datawidth <= memory.ext_datawidth %}
  assign core_write_data_{{ bank }} = rdata[{{ (memory.datawidth * (bank+1) -1) % memory.ext_datawidth }}:{{ (memory.datawidth * bank) % memory.ext_datawidth }}];
  {%- else %}
  assign core_write_data_{{ bank }} = { rdata, core_write_data_buf_{{ bank }}[W_D-1:W_EXT_D] };
  {%- endif %}
 {%- else %}
  {%- if memory.datawidth <= memory.ext_datawidth %}
  assign core_write_data_{{ bank }} = rdata;
  {%- else %}
  assign core_write_data_{{ bank }} = { rdata, core_write_data_buf_{{ bank }}[W_D-1:W_EXT_D] };
  {%- endif %}
 {%- endif %}
{%- endfor %}

  assign next_wdata = 
{%- if memory.scattergather %}
 {%- if memory.datawidth <= memory.ext_datawidth %}
  {%- for rank in range(memory.numranks) %}
    (d_cur_rank == {{ rank }})?
    { {% for b in range(int(memory.length/memory.numranks)-1, -1, -1) %}core_read_data_{{ rank * int(memory.length/memory.numranks) + b }}{% if loop.index < int(memory.length/memory.numranks) %}, {% endif %}{% endfor %} }:
  {%- endfor %}
    'hx;
 {%- else %}
  {%- for rank in range(memory.numranks) %}
    (d_cur_rank == {{ rank }})?
    core_read_data_{{ int(rank / int(memory.datawidth/memory.ext_datawidth)) }}[{{ (rank % int(memory.datawidth/memory.ext_datawidth)) + 1 }}*W_EXT_D-1:{{ (rank % int(memory.datawidth/memory.ext_datawidth)) }}*W_EXT_D]:
  {%- endfor %}
    'hx;
 {%- endif %}
{%- else %}
 {%- if memory.datawidth <= memory.ext_datawidth %}
  {%- for page in range(memory.numpages) %}
    (d_cur_page == {{ page }})? core_read_data_{{ page }}:
  {%- endfor %}
    'hx;
 {%- else %}
  {%- for page in range(memory.numpages) %}
    (d_cur_page == {{ page }})?
     (
   {%- for rank in range(memory.numranks) %}
      (d_cur_rank == {{ rank }})? core_read_data_{{ page }}[{{ (rank + 1)* memory.ext_datawidth }}:{{ rank * memory.ext_datawidth }}]:
   {%- endfor %}
      'hx
       ):
  {%- endfor %}
    'hx;
 {%- endif %}
{%- endif %}

  assign wvalid = write_offchip_busy && (d_core_read_active || (d_wvalid && !d_wready));
  assign wdata = d_core_read_active? next_wdata : d_wdata;
  assign wlast = write_count == 0;

  always @(posedge ACLK) begin
    if(aresetn_rrr == 0) begin
      read_offchip_busy <= 0;
      write_offchip_busy <= 0;
      read_count <= 0;
      write_count <= 0;
      cur_core_addr <= 0;
      cur_rank <= 0;
      d_cur_rank <= 0;
{%- if not memory.scattergather %}
      cur_page <= 0;
      d_cur_page <= 0;
{%- endif %}
{%- for bank in range(memory.length) %}
      core_write_data_buf_{{ bank }} <= 0;
{%- endfor %}

    //------------------------------------------------------------------------------
    // Off-chip -> BRAM
    //------------------------------------------------------------------------------
    end else if(read_offchip_busy) begin
      if(rvalid) begin
        read_count <= read_count - 1;
        if(read_count == 1) begin
          read_offchip_busy <= 0;
        end

{%- if memory.scattergather %}
 {%- for bank in range(memory.length) %}
  {%- if memory.datawidth <= memory.ext_datawidth %}
        core_write_data_buf_{{ bank }} <= rdata[{{ (memory.datawidth * (bank+1) -1) % memory.ext_datawidth }}:{{ (memory.datawidth * bank) % memory.ext_datawidth }}];
  {%- else %}
        core_write_data_buf_{{ bank }} <= { rdata, core_write_data_buf_{{ bank }}[W_D-1:W_EXT_D] };
  {%- endif %}
 {%- endfor %}
        if(cur_rank < NUM_RANKS-1) begin
          cur_rank <= cur_rank + 1;
        end else begin
          cur_rank <= 0;
          cur_core_addr <= cur_core_addr + 1;
        end
{%- else %}
 {%- for bank in range(memory.length) %}
  {%- if memory.datawidth <= memory.ext_datawidth %}
        core_write_data_buf_{{ bank }} <= rdata;
  {%- else %}
        core_write_data_buf_{{ bank }} <= { rdata, core_write_data_buf_{{ bank }}[W_D-1:W_EXT_D] };
  {%- endif %}
 {%- endfor %}
        if(cur_rank < NUM_RANKS-1) begin
          cur_rank <= cur_rank + 1;
        end else if(cur_core_addr < 2**W_A-1) begin
          cur_core_addr <= cur_core_addr + 1;
          cur_rank <= 0;
        end else begin
          cur_core_addr <= 0;
          cur_rank <= 0;
          cur_page <= cur_page + 1;
        end
{%- endif %}
      end

    //------------------------------------------------------------------------------
    // BRAM -> Off-chip
    //------------------------------------------------------------------------------
    end else if(write_offchip_busy) begin
      if((!wvalid || wready) && write_count > 0) begin
        write_count <= write_count - 1;

        d_cur_rank <= cur_rank;

{%- if not memory.scattergather %}
        d_cur_page <= cur_page;
{%- endif %}

{%- if memory.scattergather %}
        if(cur_rank < NUM_RANKS-1) begin
          cur_rank <= cur_rank + 1;
        end else begin
          cur_rank <= 0;
          cur_core_addr <= cur_core_addr + 1;
        end
{%- else %}
        if(cur_rank < NUM_RANKS-1) begin
          cur_rank <= cur_rank + 1;
        end else if(cur_core_addr < 2**W_A-1) begin
          cur_core_addr <= cur_core_addr + 1;
          cur_rank <= 0;
        end else begin
          cur_core_addr <= 0;
          cur_rank <= 0;
          cur_page <= cur_page + 1;
        end
{%- endif %}
      end

      //if(bvalid) begin
      //  write_offchip_busy <= 0;
      //end
      if(wvalid && wready && wlast) begin
        write_offchip_busy <= 0;
      end

    //------------------------------------------------------------------------------
    // New Command
    //------------------------------------------------------------------------------
    end else if(d_issued_deq) begin
      // Off-chip -> BRAM
      if(issued_head_write_enable) begin
        read_offchip_busy <= 1;
        read_count <= issued_head_word_size;
        if(!issued_head_burst_trunc) cur_rank <= 0;
{%- if memory.scattergather %}
        if(!issued_head_burst_trunc) cur_core_addr <= issued_head_core_addr;
{%- else %}
        if(!issued_head_burst_trunc) cur_core_addr <= issued_head_core_addr[W_A-1:0];
        if(!issued_head_burst_trunc) cur_page <= issued_head_core_addr >> W_A;
{%- endif %}

      // BRAM -> Off-chip
      end else if(issued_head_read_enable) begin
        write_offchip_busy <= 1;
        if(!issued_head_burst_trunc) cur_rank <= 0;
{%- if memory.scattergather %}
        write_count <= issued_head_word_size;
        if(!issued_head_burst_trunc) cur_core_addr <= issued_head_core_addr;
{%- else %}
        write_count <= issued_head_word_size;
        if(!issued_head_burst_trunc) cur_core_addr <= issued_head_core_addr[W_A-1:0];
        if(!issued_head_burst_trunc) cur_page <= issued_head_core_addr >> W_A;
{%- endif %}
      end
    end
  end
  
endmodule
{% endfor %}
// Thread "{{ thread.name }}" END
{%- endfor %}

