data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v
1: b'%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:2: Cannot find include file: tcu_defines.vh\n`include "tcu_defines.vh" \n         ^~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog,data/full_repos/permissive/463204869/tcu_defines.vh\n             data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog,data/full_repos/permissive/463204869/tcu_defines.vh.v\n             data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog,data/full_repos/permissive/463204869/tcu_defines.vh.sv\n             tcu_defines.vh\n             tcu_defines.vh.v\n             tcu_defines.vh.sv\n             obj_dir/tcu_defines.vh\n             obj_dir/tcu_defines.vh.v\n             obj_dir/tcu_defines.vh.sv\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:5: Cannot find include file: tcu_parameter.vh\n    `include "tcu_parameter.vh" \n             ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:6: Cannot find include file: noc_parameter.vh\n    ,`include "noc_parameter.vh" \n              ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:88: Cannot find include file: tcu_functions.v\n    `include "tcu_functions.v" \n             ^~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:6: syntax error, unexpected \',\', expecting \'[\'\n    , \n    ^\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:8: syntax error, unexpected \')\', expecting \';\'\n)(\n^\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:10: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          reset_n_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:11: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          tcu_reset_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:13: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire    [NOC_CHIPID_SIZE-1:0] home_chipid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:14: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire [TCU_FLITCOUNT_SIZE-1:0] pmp_drop_flit_count_o, \n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:18: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output reg                           reg_en_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:19: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output wire  [TCU_REG_ADDR_SIZE-1:0] reg_addr_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:20: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire  [TCU_REG_DATA_SIZE-1:0] reg_rdata_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:21: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          reg_stall_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:25: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          noc_in_tx_wrreq_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:26: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          noc_in_tx_burst_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:27: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire                          noc_in_tx_arq_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:28: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_BSEL_SIZE-1:0] noc_in_tx_bsel_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:29: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire    [NOC_CHIPID_SIZE-1:0] noc_in_tx_src_chipid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:30: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire     [NOC_MODID_SIZE-1:0] noc_in_tx_src_modid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:31: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire    [NOC_CHIPID_SIZE-1:0] noc_in_tx_trg_chipid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:32: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire     [NOC_MODID_SIZE-1:0] noc_in_tx_trg_modid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:33: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_MODE_SIZE-1:0] noc_in_tx_mode_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:34: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_ADDR_SIZE-1:0] noc_in_tx_addr_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:35: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_DATA_SIZE-1:0] noc_in_tx_data0_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:36: syntax error, unexpected input, expecting IDENTIFIER or do or final\n    input  wire      [NOC_DATA_SIZE-1:0] noc_in_tx_data1_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:37: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire                          noc_in_tx_stall_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:39: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output reg                           noc_in_rx_wrreq_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:40: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg                           noc_in_rx_burst_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:41: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg                           noc_in_rx_arq_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:42: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg       [NOC_BSEL_SIZE-1:0] noc_in_rx_bsel_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:43: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg     [NOC_CHIPID_SIZE-1:0] noc_in_rx_src_chipid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:44: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg      [NOC_MODID_SIZE-1:0] noc_in_rx_src_modid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:45: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg     [NOC_CHIPID_SIZE-1:0] noc_in_rx_trg_chipid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:46: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg      [NOC_MODID_SIZE-1:0] noc_in_rx_trg_modid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:47: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg       [NOC_MODE_SIZE-1:0] noc_in_rx_mode_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:48: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg       [NOC_ADDR_SIZE-1:0] noc_in_rx_addr_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:49: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg       [NOC_DATA_SIZE-1:0] noc_in_rx_data0_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:50: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output reg       [NOC_DATA_SIZE-1:0] noc_in_rx_data1_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:51: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  wire                          noc_in_rx_stall_i,\n    ^~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:55: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output reg                           noc_out_tx_wrreq_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:56: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output wire                          noc_out_tx_burst_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:57: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire                          noc_out_tx_arq_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:58: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire      [NOC_BSEL_SIZE-1:0] noc_out_tx_bsel_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:59: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire    [NOC_CHIPID_SIZE-1:0] noc_out_tx_src_chipid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:60: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire     [NOC_MODID_SIZE-1:0] noc_out_tx_src_modid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:61: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire    [NOC_CHIPID_SIZE-1:0] noc_out_tx_trg_chipid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:62: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire     [NOC_MODID_SIZE-1:0] noc_out_tx_trg_modid_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:63: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire      [NOC_MODE_SIZE-1:0] noc_out_tx_mode_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/463204869/units/tcu/source/rtl/verilog/tcu_pmp.v:64: syntax error, unexpected output, expecting IDENTIFIER or do or final\n    output wire      [NOC_ADDR_SIZE-1:0] noc_out_tx_addr_o,\n    ^~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module tcu_pmp #(
    `include "tcu_parameter.vh"
    ,`include "noc_parameter.vh"
    ,parameter HOME_MODID = {NOC_MODID_SIZE{1'b0}}
)(
    input  wire                          clk_i,
    input  wire                          reset_n_i,
    input  wire                          tcu_reset_i,

    input  wire    [NOC_CHIPID_SIZE-1:0] home_chipid_i,
    output wire [TCU_FLITCOUNT_SIZE-1:0] pmp_drop_flit_count_o, 



    output reg                           reg_en_o,
    output wire  [TCU_REG_ADDR_SIZE-1:0] reg_addr_o,
    input  wire  [TCU_REG_DATA_SIZE-1:0] reg_rdata_i,
    input  wire                          reg_stall_i,



    input  wire                          noc_in_tx_wrreq_i,
    input  wire                          noc_in_tx_burst_i,
    input  wire                          noc_in_tx_arq_i,
    input  wire      [NOC_BSEL_SIZE-1:0] noc_in_tx_bsel_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_in_tx_src_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_in_tx_src_modid_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_in_tx_trg_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_in_tx_trg_modid_i,
    input  wire      [NOC_MODE_SIZE-1:0] noc_in_tx_mode_i,
    input  wire      [NOC_ADDR_SIZE-1:0] noc_in_tx_addr_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_in_tx_data0_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_in_tx_data1_i,
    output wire                          noc_in_tx_stall_o,

    output reg                           noc_in_rx_wrreq_o,
    output reg                           noc_in_rx_burst_o,
    output reg                           noc_in_rx_arq_o,
    output reg       [NOC_BSEL_SIZE-1:0] noc_in_rx_bsel_o,
    output reg     [NOC_CHIPID_SIZE-1:0] noc_in_rx_src_chipid_o,
    output reg      [NOC_MODID_SIZE-1:0] noc_in_rx_src_modid_o,
    output reg     [NOC_CHIPID_SIZE-1:0] noc_in_rx_trg_chipid_o,
    output reg      [NOC_MODID_SIZE-1:0] noc_in_rx_trg_modid_o,
    output reg       [NOC_MODE_SIZE-1:0] noc_in_rx_mode_o,
    output reg       [NOC_ADDR_SIZE-1:0] noc_in_rx_addr_o,
    output reg       [NOC_DATA_SIZE-1:0] noc_in_rx_data0_o,
    output reg       [NOC_DATA_SIZE-1:0] noc_in_rx_data1_o,
    input  wire                          noc_in_rx_stall_i,



    output reg                           noc_out_tx_wrreq_o,
    output wire                          noc_out_tx_burst_o,
    output wire                          noc_out_tx_arq_o,
    output wire      [NOC_BSEL_SIZE-1:0] noc_out_tx_bsel_o,
    output wire    [NOC_CHIPID_SIZE-1:0] noc_out_tx_src_chipid_o,
    output wire     [NOC_MODID_SIZE-1:0] noc_out_tx_src_modid_o,
    output wire    [NOC_CHIPID_SIZE-1:0] noc_out_tx_trg_chipid_o,
    output wire     [NOC_MODID_SIZE-1:0] noc_out_tx_trg_modid_o,
    output wire      [NOC_MODE_SIZE-1:0] noc_out_tx_mode_o,
    output wire      [NOC_ADDR_SIZE-1:0] noc_out_tx_addr_o,
    output wire      [NOC_DATA_SIZE-1:0] noc_out_tx_data0_o,
    output wire      [NOC_DATA_SIZE-1:0] noc_out_tx_data1_o,
    input  wire                          noc_out_tx_stall_i,

    input  wire                          noc_out_rx_wrreq_i,
    input  wire                          noc_out_rx_burst_i,
    input  wire                          noc_out_rx_arq_i,
    input  wire      [NOC_BSEL_SIZE-1:0] noc_out_rx_bsel_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_out_rx_src_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_out_rx_src_modid_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_out_rx_trg_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_out_rx_trg_modid_i,
    input  wire      [NOC_MODE_SIZE-1:0] noc_out_rx_mode_i,
    input  wire      [NOC_ADDR_SIZE-1:0] noc_out_rx_addr_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_out_rx_data0_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_out_rx_data1_i,
    output reg                           noc_out_rx_stall_o,



    output reg   [TCU_LOG_DATA_SIZE-1:0] tcu_log_pmp_o
);

    `include "tcu_functions.v"

    localparam FIFO_WIDTH = NOC_HEADER_SIZE + NOC_PAYLOAD_SIZE;

    localparam PMP_STATES_SIZE   = 4;
    localparam S_PMP_IDLE        = 4'h0;
    localparam S_PMP_READEP_REG1 = 4'h1;
    localparam S_PMP_READEP_REG2 = 4'h2;
    localparam S_PMP_READEP_REG3 = 4'h3;
    localparam S_PMP_READEP_REG4 = 4'h4;
    localparam S_PMP_CHECK_EP    = 4'h5;
    localparam S_PMP_RUN         = 4'h6;
    localparam S_PMP_ERROR_RSP   = 4'h7;
    localparam S_PMP_DROP_PACKET = 4'h8;
    localparam S_PMP_FINISH      = 4'hF;

    reg [PMP_STATES_SIZE-1:0] pmp_state, next_pmp_state;


    reg                         r_reg_en;
    reg [TCU_REG_ADDR_SIZE-1:0] r_reg_addr, rin_reg_addr;

    reg r_noc_in_tx_burst;
    reg r_noc_out_rx_burst;

    reg [63:0] r_mep_0, rin_mep_0;
    reg [63:0] r_mep_1, rin_mep_1;
    reg [63:0] r_mep_2, rin_mep_2;


    reg [15:0] r_size, rin_size;


    reg [TCU_FLITCOUNT_SIZE-1:0] r_drop_flit_count, rin_drop_flit_count;


    reg  fifo_pop;
    wire fifo_push = noc_in_tx_wrreq_i && !noc_in_tx_stall_o;
    wire fifo_empty;
    wire fifo_full;

    wire [FIFO_WIDTH-1:0] fifo_dataout;
    wire [FIFO_WIDTH-1:0] fifo_datain = r_noc_in_tx_burst ? {
        noc_in_tx_burst_i,
        noc_in_tx_arq_i,
        noc_in_tx_bsel_i,
        noc_in_tx_data1_i,
        noc_in_tx_data0_i} : {
        noc_in_tx_burst_i,
        noc_in_tx_arq_i,
        noc_in_tx_bsel_i,
        noc_in_tx_src_modid_i,
        noc_in_tx_src_chipid_i,
        noc_in_tx_trg_modid_i,
        noc_in_tx_trg_chipid_i,
        noc_in_tx_mode_i,
        noc_in_tx_addr_i,
        noc_in_tx_data0_i};

    wire                       fifo_dataout_burst      = fifo_dataout[FIFO_WIDTH-1];
    wire                       fifo_dataout_arq        = fifo_dataout[FIFO_WIDTH-NOC_BURST_SIZE-1];
    wire   [NOC_BSEL_SIZE-1:0] fifo_dataout_bsel       = fifo_dataout[NOC_BSEL_SIZE+2*NOC_CHIPID_SIZE+2*NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        2*NOC_CHIPID_SIZE+2*NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire  [NOC_MODID_SIZE-1:0] fifo_dataout_src_modid  = fifo_dataout[2*NOC_CHIPID_SIZE+2*NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        2*NOC_CHIPID_SIZE+NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire [NOC_CHIPID_SIZE-1:0] fifo_dataout_src_chipid = fifo_dataout[2*NOC_CHIPID_SIZE+NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        NOC_CHIPID_SIZE+NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire  [NOC_MODID_SIZE-1:0] fifo_dataout_trg_modid  = fifo_dataout[NOC_CHIPID_SIZE+NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        NOC_CHIPID_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire [NOC_CHIPID_SIZE-1:0] fifo_dataout_trg_chipid = fifo_dataout[NOC_CHIPID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire   [NOC_MODE_SIZE-1:0] fifo_dataout_mode       = fifo_dataout[NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 : NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire   [NOC_ADDR_SIZE-1:0] fifo_dataout_addr       = fifo_dataout[NOC_ADDR_SIZE+NOC_DATA_SIZE-1 : NOC_DATA_SIZE];
    wire   [NOC_DATA_SIZE-1:0] fifo_dataout_data1      = fifo_dataout[2*NOC_DATA_SIZE-1 : NOC_DATA_SIZE];
    wire   [NOC_DATA_SIZE-1:0] fifo_dataout_data0      = fifo_dataout[NOC_DATA_SIZE-1 : 0];


    wire  [3:0] start_shift  = ~fifo_dataout_bsel[3:0];
    wire  [4:0] end_shift    = fifo_dataout_bsel[7:4] + 5'd1;
    wire [12:0] burst_length = fifo_dataout_data0[12:0];

    wire  [3:0] bsel_count_ones = count_ones8(fifo_dataout_bsel);



    wire [NOC_ADDR_SIZE-1:0] pmp_addr = fifo_dataout_addr - 32'h10000000;


    wire [1:0] epidx = pmp_addr[31:30];

    wire [29:0] pmp_offset = pmp_addr[29:0];

    wire [NOC_MODE_SIZE-1:0] pmp_mode = fifo_dataout_mode;
    wire [1:0] access_rw = ((pmp_mode == MODE_READ_REQ) || (pmp_mode == MODE_READ_REQ_2)) ? TCU_MEMFLAG_R :
                            ((pmp_mode == MODE_WRITE_POSTED) || (pmp_mode == MODE_WRITE_POSTED_2) || (pmp_mode == MODE_READ_RSP) || (pmp_mode == MODE_READ_RSP_2)) ? TCU_MEMFLAG_W :
                            2'h0;



    wire [TCU_EP_TYPE_SIZE-1:0] mep_type    = r_mep_0[TCU_EP_TYPE_SIZE-1:0];
    wire [TCU_MEMFLAG_SIZE-1:0] mep_memflag = r_mep_0[TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE-1 : TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE];
    wire    [TCU_PEID_SIZE-1:0] mep_pe      = r_mep_0[TCU_PEID_SIZE+TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE-1 : TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE];
    wire  [TCU_CHIPID_SIZE-1:0] mep_chip    = r_mep_0[TCU_CHIPID_SIZE+TCU_PEID_SIZE+TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE-1 : TCU_PEID_SIZE+TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE];
    wire                 [63:0] mep_addr    = r_mep_1;
    wire                 [63:0] mep_size    = r_mep_2;



    always @(posedge clk_i or negedge reset_n_i) begin
        if (reset_n_i == 1'b0) begin
            pmp_state <= S_PMP_IDLE;

            r_reg_en <= 1'b0;
            r_reg_addr <= {TCU_REG_ADDR_SIZE{1'b0}};

            r_noc_in_tx_burst <= 1'b0;
            r_noc_out_rx_burst <= 1'b0;

            r_mep_0 <= 64'h0;
            r_mep_1 <= 64'h0;
            r_mep_2 <= 64'h0;

            r_size <= 16'h0;

            r_drop_flit_count <= {TCU_FLITCOUNT_SIZE{1'b0}};
        end
        else begin
            pmp_state <= next_pmp_state;

            r_reg_en <= reg_en_o;
            r_reg_addr <= rin_reg_addr;

            r_noc_in_tx_burst <= (noc_in_tx_wrreq_i && !noc_in_tx_stall_o) ? noc_in_tx_burst_i : r_noc_in_tx_burst;
            r_noc_out_rx_burst <= (noc_out_rx_wrreq_i && !noc_out_rx_stall_o) ? noc_out_rx_burst_i : r_noc_out_rx_burst;

            r_mep_0 <= rin_mep_0;
            r_mep_1 <= rin_mep_1;
            r_mep_2 <= rin_mep_2;

            r_size <= rin_size;

            r_drop_flit_count <= rin_drop_flit_count;
        end
    end


    always @* begin
        rin_drop_flit_count = r_drop_flit_count;

        if (tcu_reset_i) begin
            rin_drop_flit_count = {TCU_FLITCOUNT_SIZE{1'b0}};
        end
        else if ((pmp_state == S_PMP_DROP_PACKET) && !fifo_empty) begin
            rin_drop_flit_count = r_drop_flit_count + 1;
        end
    end



    sync_fifo #(
        .DATA_WIDTH (FIFO_WIDTH),
        .ADDR_WIDTH (2)
    ) req_wfifo (
        .clk_i		(clk_i),
        .resetn_i	(reset_n_i),

        .wr_en_i	(fifo_push),
        .wdata_i	(fifo_datain),
        .wfull_o	(fifo_full),

        .rd_en_i	(fifo_pop),
        .rdata_o	(fifo_dataout),
        .rempty_o	(fifo_empty)
    );

    




    always @* begin
        next_pmp_state = pmp_state;

        reg_en_o = 1'b0;
        rin_reg_addr = r_reg_addr;

        rin_mep_0 = r_mep_0;
        rin_mep_1 = r_mep_1;
        rin_mep_2 = r_mep_2;

        rin_size = r_size;

        fifo_pop = 1'b0;

        noc_out_tx_wrreq_o = 1'b0;

        tcu_log_pmp_o = TCU_LOG_NONE;


        case (pmp_state)



            S_PMP_IDLE: begin
                if (!fifo_empty) begin
                    rin_reg_addr = TCU_REGADDR_EP_START + epidx*TCU_EP_REG_SIZE;
                    rin_size = 'd0;


                    if (access_rw & TCU_MEMFLAG_W) begin

                        if (fifo_dataout_burst) begin
                            rin_size = {burst_length, 4'h0} - start_shift - (5'd16 - end_shift);
                        end


                        else begin
                            rin_size = bsel_count_ones;
                        end
                    end


                    else if ((access_rw & TCU_MEMFLAG_R) && !fifo_dataout_burst) begin
                        rin_size = fifo_dataout_data0[NOC_DATA_SIZE-1:32];
                    end

                    next_pmp_state = S_PMP_READEP_REG1;
                end
            end




            S_PMP_READEP_REG1: begin
                if (!reg_stall_i) begin
                    reg_en_o = 1'b1;
                    rin_reg_addr = r_reg_addr + 'd8;
                    next_pmp_state = S_PMP_READEP_REG2;
                end
            end

            S_PMP_READEP_REG2: begin
                if (r_reg_en) begin
                    rin_mep_0 = reg_rdata_i;
                end

                if (!reg_stall_i) begin
                    reg_en_o = 1'b1;
                    rin_reg_addr = r_reg_addr + 'd8;
                    next_pmp_state = S_PMP_READEP_REG3;
                end
            end

            S_PMP_READEP_REG3: begin
                if (r_reg_en) begin
                    rin_mep_1 = reg_rdata_i;
                end

                if (!reg_stall_i) begin
                    reg_en_o = 1'b1;
                    next_pmp_state = S_PMP_READEP_REG4;
                end
            end

            S_PMP_READEP_REG4: begin
                rin_mep_2 = reg_rdata_i;
                next_pmp_state = S_PMP_CHECK_EP;
            end




            S_PMP_CHECK_EP: begin
                if ((mep_type == TCU_EP_TYPE_MEMORY) &&
                    (mep_memflag & access_rw) &&
                    ((pmp_offset + r_size) <= mep_size)) begin
                    next_pmp_state = S_PMP_RUN;
                end


                else begin
                    `TCU_DEBUG(("PMP_ACCESS_DENIED, mode: %d, addr: 0x%x, size: %0d", pmp_mode, fifo_dataout_addr, r_size));
                    tcu_log_pmp_o = {r_size, fifo_dataout_addr, pmp_mode, TCU_LOG_PMP_ACCESS_DENIED};


                    if (access_rw & TCU_MEMFLAG_R) begin
                        next_pmp_state = S_PMP_ERROR_RSP;
                    end
                    else begin
                        next_pmp_state = S_PMP_DROP_PACKET;
                    end
                end
            end

            S_PMP_RUN: begin
                if (!fifo_empty) begin
                    noc_out_tx_wrreq_o = 1'b1;

                    if (!noc_out_tx_stall_i) begin

                        if (fifo_dataout_burst) begin
                            fifo_pop = 1'b1;
                        end
                        else begin
                            next_pmp_state = S_PMP_FINISH;
                        end
                    end
                end
            end




            S_PMP_ERROR_RSP: begin
                if (!noc_out_rx_wrreq_i && !r_noc_out_rx_burst && !noc_in_rx_stall_i) begin
                    next_pmp_state = S_PMP_DROP_PACKET;
                end
            end


            S_PMP_DROP_PACKET: begin
                if (!fifo_empty) begin


                    if (fifo_dataout_burst) begin
                        fifo_pop = 1'b1;
                    end
                    else begin
                        next_pmp_state = S_PMP_FINISH;
                    end
                end
            end


            S_PMP_FINISH: begin
                fifo_pop = 1'b1;
                next_pmp_state = S_PMP_IDLE;
            end

            default: next_pmp_state = S_PMP_IDLE;
        endcase
    end




    always @* begin
        noc_in_rx_wrreq_o      = 1'b0;
        noc_in_rx_burst_o      = 1'b0;
        noc_in_rx_arq_o        = 1'b0;
        noc_in_rx_bsel_o       = {NOC_BSEL_SIZE{1'b0}};
        noc_in_rx_src_chipid_o = {NOC_CHIPID_SIZE{1'b0}};
        noc_in_rx_src_modid_o  = {NOC_MODID_SIZE{1'b0}};
        noc_in_rx_trg_chipid_o = {NOC_CHIPID_SIZE{1'b0}};
        noc_in_rx_trg_modid_o  = {NOC_MODID_SIZE{1'b0}};
        noc_in_rx_mode_o       = {NOC_MODE_SIZE{1'b0}};
        noc_in_rx_addr_o       = {NOC_ADDR_SIZE{1'b0}};
        noc_in_rx_data0_o      = {NOC_DATA_SIZE{1'b0}};
        noc_in_rx_data1_o      = {NOC_DATA_SIZE{1'b0}};
        noc_out_rx_stall_o     = 1'b1;


        if (noc_out_rx_wrreq_i) begin
            noc_in_rx_wrreq_o      = noc_out_rx_wrreq_i;
            noc_in_rx_burst_o      = noc_out_rx_burst_i;
            noc_in_rx_arq_o        = noc_out_rx_arq_i;
            noc_in_rx_bsel_o       = noc_out_rx_bsel_i;
            noc_in_rx_src_chipid_o = noc_out_rx_src_chipid_i;
            noc_in_rx_src_modid_o  = noc_out_rx_src_modid_i;
            noc_in_rx_trg_chipid_o = noc_out_rx_trg_chipid_i;
            noc_in_rx_trg_modid_o  = noc_out_rx_trg_modid_i;
            noc_in_rx_mode_o       = noc_out_rx_mode_i;
            noc_in_rx_addr_o       = noc_out_rx_addr_i;
            noc_in_rx_data0_o      = noc_out_rx_data0_i;
            noc_in_rx_data1_o      = noc_out_rx_data1_i;
            noc_out_rx_stall_o     = noc_in_rx_stall_i;
        end


        else if ((pmp_state == S_PMP_ERROR_RSP) && !r_noc_out_rx_burst) begin
            noc_in_rx_wrreq_o      = 1'b1;
            noc_in_rx_bsel_o       = {NOC_BSEL_SIZE{1'b1}};
            noc_in_rx_src_chipid_o = home_chipid_i;
            noc_in_rx_src_modid_o  = HOME_MODID;
            noc_in_rx_trg_chipid_o = home_chipid_i;
            noc_in_rx_trg_modid_o  = HOME_MODID;
            noc_in_rx_mode_o       = MODE_ERROR;
            noc_in_rx_addr_o       = fifo_dataout_addr;
            noc_in_rx_data0_o      = {NOC_DATA_SIZE{1'b0}};
        end
    end


    assign pmp_drop_flit_count_o = r_drop_flit_count;

    assign reg_addr_o = r_reg_addr;


    assign noc_out_tx_burst_o      = fifo_dataout_burst;
    assign noc_out_tx_arq_o        = fifo_dataout_arq;
    assign noc_out_tx_bsel_o       = fifo_dataout_bsel;
    assign noc_out_tx_src_modid_o  = HOME_MODID;
    assign noc_out_tx_trg_modid_o  = mep_pe;
    assign noc_out_tx_src_chipid_o = home_chipid_i;
    assign noc_out_tx_trg_chipid_o = mep_chip;
    assign noc_out_tx_mode_o       = fifo_dataout_mode;
    assign noc_out_tx_addr_o       = mep_addr + pmp_offset;
    assign noc_out_tx_data0_o      = fifo_dataout_data0;
    assign noc_out_tx_data1_o      = fifo_dataout_data1;


    assign noc_in_tx_stall_o = fifo_full;


endmodule
module tcu_pmp #(
    `include "tcu_parameter.vh"
    ,`include "noc_parameter.vh"
    ,parameter HOME_MODID = {NOC_MODID_SIZE{1'b0}}
)(
    input  wire                          clk_i,
    input  wire                          reset_n_i,
    input  wire                          tcu_reset_i,

    input  wire    [NOC_CHIPID_SIZE-1:0] home_chipid_i,
    output wire [TCU_FLITCOUNT_SIZE-1:0] pmp_drop_flit_count_o, 



    output reg                           reg_en_o,
    output wire  [TCU_REG_ADDR_SIZE-1:0] reg_addr_o,
    input  wire  [TCU_REG_DATA_SIZE-1:0] reg_rdata_i,
    input  wire                          reg_stall_i,



    input  wire                          noc_in_tx_wrreq_i,
    input  wire                          noc_in_tx_burst_i,
    input  wire                          noc_in_tx_arq_i,
    input  wire      [NOC_BSEL_SIZE-1:0] noc_in_tx_bsel_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_in_tx_src_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_in_tx_src_modid_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_in_tx_trg_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_in_tx_trg_modid_i,
    input  wire      [NOC_MODE_SIZE-1:0] noc_in_tx_mode_i,
    input  wire      [NOC_ADDR_SIZE-1:0] noc_in_tx_addr_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_in_tx_data0_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_in_tx_data1_i,
    output wire                          noc_in_tx_stall_o,

    output reg                           noc_in_rx_wrreq_o,
    output reg                           noc_in_rx_burst_o,
    output reg                           noc_in_rx_arq_o,
    output reg       [NOC_BSEL_SIZE-1:0] noc_in_rx_bsel_o,
    output reg     [NOC_CHIPID_SIZE-1:0] noc_in_rx_src_chipid_o,
    output reg      [NOC_MODID_SIZE-1:0] noc_in_rx_src_modid_o,
    output reg     [NOC_CHIPID_SIZE-1:0] noc_in_rx_trg_chipid_o,
    output reg      [NOC_MODID_SIZE-1:0] noc_in_rx_trg_modid_o,
    output reg       [NOC_MODE_SIZE-1:0] noc_in_rx_mode_o,
    output reg       [NOC_ADDR_SIZE-1:0] noc_in_rx_addr_o,
    output reg       [NOC_DATA_SIZE-1:0] noc_in_rx_data0_o,
    output reg       [NOC_DATA_SIZE-1:0] noc_in_rx_data1_o,
    input  wire                          noc_in_rx_stall_i,



    output reg                           noc_out_tx_wrreq_o,
    output wire                          noc_out_tx_burst_o,
    output wire                          noc_out_tx_arq_o,
    output wire      [NOC_BSEL_SIZE-1:0] noc_out_tx_bsel_o,
    output wire    [NOC_CHIPID_SIZE-1:0] noc_out_tx_src_chipid_o,
    output wire     [NOC_MODID_SIZE-1:0] noc_out_tx_src_modid_o,
    output wire    [NOC_CHIPID_SIZE-1:0] noc_out_tx_trg_chipid_o,
    output wire     [NOC_MODID_SIZE-1:0] noc_out_tx_trg_modid_o,
    output wire      [NOC_MODE_SIZE-1:0] noc_out_tx_mode_o,
    output wire      [NOC_ADDR_SIZE-1:0] noc_out_tx_addr_o,
    output wire      [NOC_DATA_SIZE-1:0] noc_out_tx_data0_o,
    output wire      [NOC_DATA_SIZE-1:0] noc_out_tx_data1_o,
    input  wire                          noc_out_tx_stall_i,

    input  wire                          noc_out_rx_wrreq_i,
    input  wire                          noc_out_rx_burst_i,
    input  wire                          noc_out_rx_arq_i,
    input  wire      [NOC_BSEL_SIZE-1:0] noc_out_rx_bsel_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_out_rx_src_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_out_rx_src_modid_i,
    input  wire    [NOC_CHIPID_SIZE-1:0] noc_out_rx_trg_chipid_i,
    input  wire     [NOC_MODID_SIZE-1:0] noc_out_rx_trg_modid_i,
    input  wire      [NOC_MODE_SIZE-1:0] noc_out_rx_mode_i,
    input  wire      [NOC_ADDR_SIZE-1:0] noc_out_rx_addr_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_out_rx_data0_i,
    input  wire      [NOC_DATA_SIZE-1:0] noc_out_rx_data1_i,
    output reg                           noc_out_rx_stall_o,



    output reg   [TCU_LOG_DATA_SIZE-1:0] tcu_log_pmp_o
);


    `include "tcu_functions.v"

    localparam FIFO_WIDTH = NOC_HEADER_SIZE + NOC_PAYLOAD_SIZE;

    localparam PMP_STATES_SIZE   = 4;
    localparam S_PMP_IDLE        = 4'h0;
    localparam S_PMP_READEP_REG1 = 4'h1;
    localparam S_PMP_READEP_REG2 = 4'h2;
    localparam S_PMP_READEP_REG3 = 4'h3;
    localparam S_PMP_READEP_REG4 = 4'h4;
    localparam S_PMP_CHECK_EP    = 4'h5;
    localparam S_PMP_RUN         = 4'h6;
    localparam S_PMP_ERROR_RSP   = 4'h7;
    localparam S_PMP_DROP_PACKET = 4'h8;
    localparam S_PMP_FINISH      = 4'hF;

    reg [PMP_STATES_SIZE-1:0] pmp_state, next_pmp_state;


    reg                         r_reg_en;
    reg [TCU_REG_ADDR_SIZE-1:0] r_reg_addr, rin_reg_addr;

    reg r_noc_in_tx_burst;
    reg r_noc_out_rx_burst;

    reg [63:0] r_mep_0, rin_mep_0;
    reg [63:0] r_mep_1, rin_mep_1;
    reg [63:0] r_mep_2, rin_mep_2;


    reg [15:0] r_size, rin_size;


    reg [TCU_FLITCOUNT_SIZE-1:0] r_drop_flit_count, rin_drop_flit_count;


    reg  fifo_pop;
    wire fifo_push = noc_in_tx_wrreq_i && !noc_in_tx_stall_o;
    wire fifo_empty;
    wire fifo_full;

    wire [FIFO_WIDTH-1:0] fifo_dataout;
    wire [FIFO_WIDTH-1:0] fifo_datain = r_noc_in_tx_burst ? {
        noc_in_tx_burst_i,
        noc_in_tx_arq_i,
        noc_in_tx_bsel_i,
        noc_in_tx_data1_i,
        noc_in_tx_data0_i} : {
        noc_in_tx_burst_i,
        noc_in_tx_arq_i,
        noc_in_tx_bsel_i,
        noc_in_tx_src_modid_i,
        noc_in_tx_src_chipid_i,
        noc_in_tx_trg_modid_i,
        noc_in_tx_trg_chipid_i,
        noc_in_tx_mode_i,
        noc_in_tx_addr_i,
        noc_in_tx_data0_i};

    wire                       fifo_dataout_burst      = fifo_dataout[FIFO_WIDTH-1];
    wire                       fifo_dataout_arq        = fifo_dataout[FIFO_WIDTH-NOC_BURST_SIZE-1];
    wire   [NOC_BSEL_SIZE-1:0] fifo_dataout_bsel       = fifo_dataout[NOC_BSEL_SIZE+2*NOC_CHIPID_SIZE+2*NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        2*NOC_CHIPID_SIZE+2*NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire  [NOC_MODID_SIZE-1:0] fifo_dataout_src_modid  = fifo_dataout[2*NOC_CHIPID_SIZE+2*NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        2*NOC_CHIPID_SIZE+NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire [NOC_CHIPID_SIZE-1:0] fifo_dataout_src_chipid = fifo_dataout[2*NOC_CHIPID_SIZE+NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        NOC_CHIPID_SIZE+NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire  [NOC_MODID_SIZE-1:0] fifo_dataout_trg_modid  = fifo_dataout[NOC_CHIPID_SIZE+NOC_MODID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        NOC_CHIPID_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire [NOC_CHIPID_SIZE-1:0] fifo_dataout_trg_chipid = fifo_dataout[NOC_CHIPID_SIZE+NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 :
                                                                        NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire   [NOC_MODE_SIZE-1:0] fifo_dataout_mode       = fifo_dataout[NOC_MODE_SIZE+NOC_ADDR_SIZE+NOC_DATA_SIZE-1 : NOC_ADDR_SIZE+NOC_DATA_SIZE];
    wire   [NOC_ADDR_SIZE-1:0] fifo_dataout_addr       = fifo_dataout[NOC_ADDR_SIZE+NOC_DATA_SIZE-1 : NOC_DATA_SIZE];
    wire   [NOC_DATA_SIZE-1:0] fifo_dataout_data1      = fifo_dataout[2*NOC_DATA_SIZE-1 : NOC_DATA_SIZE];
    wire   [NOC_DATA_SIZE-1:0] fifo_dataout_data0      = fifo_dataout[NOC_DATA_SIZE-1 : 0];


    wire  [3:0] start_shift  = ~fifo_dataout_bsel[3:0];
    wire  [4:0] end_shift    = fifo_dataout_bsel[7:4] + 5'd1;
    wire [12:0] burst_length = fifo_dataout_data0[12:0];

    wire  [3:0] bsel_count_ones = count_ones8(fifo_dataout_bsel);



    wire [NOC_ADDR_SIZE-1:0] pmp_addr = fifo_dataout_addr - 32'h10000000;


    wire [1:0] epidx = pmp_addr[31:30];

    wire [29:0] pmp_offset = pmp_addr[29:0];

    wire [NOC_MODE_SIZE-1:0] pmp_mode = fifo_dataout_mode;
    wire [1:0] access_rw = ((pmp_mode == MODE_READ_REQ) || (pmp_mode == MODE_READ_REQ_2)) ? TCU_MEMFLAG_R :
                            ((pmp_mode == MODE_WRITE_POSTED) || (pmp_mode == MODE_WRITE_POSTED_2) || (pmp_mode == MODE_READ_RSP) || (pmp_mode == MODE_READ_RSP_2)) ? TCU_MEMFLAG_W :
                            2'h0;



    wire [TCU_EP_TYPE_SIZE-1:0] mep_type    = r_mep_0[TCU_EP_TYPE_SIZE-1:0];
    wire [TCU_MEMFLAG_SIZE-1:0] mep_memflag = r_mep_0[TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE-1 : TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE];
    wire    [TCU_PEID_SIZE-1:0] mep_pe      = r_mep_0[TCU_PEID_SIZE+TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE-1 : TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE];
    wire  [TCU_CHIPID_SIZE-1:0] mep_chip    = r_mep_0[TCU_CHIPID_SIZE+TCU_PEID_SIZE+TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE-1 : TCU_PEID_SIZE+TCU_MEMFLAG_SIZE+TCU_VPEID_SIZE+TCU_EP_TYPE_SIZE];
    wire                 [63:0] mep_addr    = r_mep_1;
    wire                 [63:0] mep_size    = r_mep_2;



    always @(posedge clk_i or negedge reset_n_i) begin
        if (reset_n_i == 1'b0) begin
            pmp_state <= S_PMP_IDLE;

            r_reg_en <= 1'b0;
            r_reg_addr <= {TCU_REG_ADDR_SIZE{1'b0}};

            r_noc_in_tx_burst <= 1'b0;
            r_noc_out_rx_burst <= 1'b0;

            r_mep_0 <= 64'h0;
            r_mep_1 <= 64'h0;
            r_mep_2 <= 64'h0;

            r_size <= 16'h0;

            r_drop_flit_count <= {TCU_FLITCOUNT_SIZE{1'b0}};
        end
        else begin
            pmp_state <= next_pmp_state;

            r_reg_en <= reg_en_o;
            r_reg_addr <= rin_reg_addr;

            r_noc_in_tx_burst <= (noc_in_tx_wrreq_i && !noc_in_tx_stall_o) ? noc_in_tx_burst_i : r_noc_in_tx_burst;
            r_noc_out_rx_burst <= (noc_out_rx_wrreq_i && !noc_out_rx_stall_o) ? noc_out_rx_burst_i : r_noc_out_rx_burst;

            r_mep_0 <= rin_mep_0;
            r_mep_1 <= rin_mep_1;
            r_mep_2 <= rin_mep_2;

            r_size <= rin_size;

            r_drop_flit_count <= rin_drop_flit_count;
        end
    end


    always @* begin
        rin_drop_flit_count = r_drop_flit_count;

        if (tcu_reset_i) begin
            rin_drop_flit_count = {TCU_FLITCOUNT_SIZE{1'b0}};
        end
        else if ((pmp_state == S_PMP_DROP_PACKET) && !fifo_empty) begin
            rin_drop_flit_count = r_drop_flit_count + 1;
        end
    end



    sync_fifo #(
        .DATA_WIDTH (FIFO_WIDTH),
        .ADDR_WIDTH (2)
    ) req_wfifo (
        .clk_i		(clk_i),
        .resetn_i	(reset_n_i),

        .wr_en_i	(fifo_push),
        .wdata_i	(fifo_datain),
        .wfull_o	(fifo_full),

        .rd_en_i	(fifo_pop),
        .rdata_o	(fifo_dataout),
        .rempty_o	(fifo_empty)
    );

    




    always @* begin
        next_pmp_state = pmp_state;

        reg_en_o = 1'b0;
        rin_reg_addr = r_reg_addr;

        rin_mep_0 = r_mep_0;
        rin_mep_1 = r_mep_1;
        rin_mep_2 = r_mep_2;

        rin_size = r_size;

        fifo_pop = 1'b0;

        noc_out_tx_wrreq_o = 1'b0;

        tcu_log_pmp_o = TCU_LOG_NONE;


        case (pmp_state)



            S_PMP_IDLE: begin
                if (!fifo_empty) begin
                    rin_reg_addr = TCU_REGADDR_EP_START + epidx*TCU_EP_REG_SIZE;
                    rin_size = 'd0;


                    if (access_rw & TCU_MEMFLAG_W) begin

                        if (fifo_dataout_burst) begin
                            rin_size = {burst_length, 4'h0} - start_shift - (5'd16 - end_shift);
                        end


                        else begin
                            rin_size = bsel_count_ones;
                        end
                    end


                    else if ((access_rw & TCU_MEMFLAG_R) && !fifo_dataout_burst) begin
                        rin_size = fifo_dataout_data0[NOC_DATA_SIZE-1:32];
                    end

                    next_pmp_state = S_PMP_READEP_REG1;
                end
            end




            S_PMP_READEP_REG1: begin
                if (!reg_stall_i) begin
                    reg_en_o = 1'b1;
                    rin_reg_addr = r_reg_addr + 'd8;
                    next_pmp_state = S_PMP_READEP_REG2;
                end
            end

            S_PMP_READEP_REG2: begin
                if (r_reg_en) begin
                    rin_mep_0 = reg_rdata_i;
                end

                if (!reg_stall_i) begin
                    reg_en_o = 1'b1;
                    rin_reg_addr = r_reg_addr + 'd8;
                    next_pmp_state = S_PMP_READEP_REG3;
                end
            end

            S_PMP_READEP_REG3: begin
                if (r_reg_en) begin
                    rin_mep_1 = reg_rdata_i;
                end

                if (!reg_stall_i) begin
                    reg_en_o = 1'b1;
                    next_pmp_state = S_PMP_READEP_REG4;
                end
            end

            S_PMP_READEP_REG4: begin
                rin_mep_2 = reg_rdata_i;
                next_pmp_state = S_PMP_CHECK_EP;
            end




            S_PMP_CHECK_EP: begin
                if ((mep_type == TCU_EP_TYPE_MEMORY) &&
                    (mep_memflag & access_rw) &&
                    ((pmp_offset + r_size) <= mep_size)) begin
                    next_pmp_state = S_PMP_RUN;
                end


                else begin
                    `TCU_DEBUG(("PMP_ACCESS_DENIED, mode: %d, addr: 0x%x, size: %0d", pmp_mode, fifo_dataout_addr, r_size));
                    tcu_log_pmp_o = {r_size, fifo_dataout_addr, pmp_mode, TCU_LOG_PMP_ACCESS_DENIED};


                    if (access_rw & TCU_MEMFLAG_R) begin
                        next_pmp_state = S_PMP_ERROR_RSP;
                    end
                    else begin
                        next_pmp_state = S_PMP_DROP_PACKET;
                    end
                end
            end

            S_PMP_RUN: begin
                if (!fifo_empty) begin
                    noc_out_tx_wrreq_o = 1'b1;

                    if (!noc_out_tx_stall_i) begin

                        if (fifo_dataout_burst) begin
                            fifo_pop = 1'b1;
                        end
                        else begin
                            next_pmp_state = S_PMP_FINISH;
                        end
                    end
                end
            end




            S_PMP_ERROR_RSP: begin
                if (!noc_out_rx_wrreq_i && !r_noc_out_rx_burst && !noc_in_rx_stall_i) begin
                    next_pmp_state = S_PMP_DROP_PACKET;
                end
            end


            S_PMP_DROP_PACKET: begin
                if (!fifo_empty) begin


                    if (fifo_dataout_burst) begin
                        fifo_pop = 1'b1;
                    end
                    else begin
                        next_pmp_state = S_PMP_FINISH;
                    end
                end
            end


            S_PMP_FINISH: begin
                fifo_pop = 1'b1;
                next_pmp_state = S_PMP_IDLE;
            end

            default: next_pmp_state = S_PMP_IDLE;
        endcase
    end




    always @* begin
        noc_in_rx_wrreq_o      = 1'b0;
        noc_in_rx_burst_o      = 1'b0;
        noc_in_rx_arq_o        = 1'b0;
        noc_in_rx_bsel_o       = {NOC_BSEL_SIZE{1'b0}};
        noc_in_rx_src_chipid_o = {NOC_CHIPID_SIZE{1'b0}};
        noc_in_rx_src_modid_o  = {NOC_MODID_SIZE{1'b0}};
        noc_in_rx_trg_chipid_o = {NOC_CHIPID_SIZE{1'b0}};
        noc_in_rx_trg_modid_o  = {NOC_MODID_SIZE{1'b0}};
        noc_in_rx_mode_o       = {NOC_MODE_SIZE{1'b0}};
        noc_in_rx_addr_o       = {NOC_ADDR_SIZE{1'b0}};
        noc_in_rx_data0_o      = {NOC_DATA_SIZE{1'b0}};
        noc_in_rx_data1_o      = {NOC_DATA_SIZE{1'b0}};
        noc_out_rx_stall_o     = 1'b1;


        if (noc_out_rx_wrreq_i) begin
            noc_in_rx_wrreq_o      = noc_out_rx_wrreq_i;
            noc_in_rx_burst_o      = noc_out_rx_burst_i;
            noc_in_rx_arq_o        = noc_out_rx_arq_i;
            noc_in_rx_bsel_o       = noc_out_rx_bsel_i;
            noc_in_rx_src_chipid_o = noc_out_rx_src_chipid_i;
            noc_in_rx_src_modid_o  = noc_out_rx_src_modid_i;
            noc_in_rx_trg_chipid_o = noc_out_rx_trg_chipid_i;
            noc_in_rx_trg_modid_o  = noc_out_rx_trg_modid_i;
            noc_in_rx_mode_o       = noc_out_rx_mode_i;
            noc_in_rx_addr_o       = noc_out_rx_addr_i;
            noc_in_rx_data0_o      = noc_out_rx_data0_i;
            noc_in_rx_data1_o      = noc_out_rx_data1_i;
            noc_out_rx_stall_o     = noc_in_rx_stall_i;
        end


        else if ((pmp_state == S_PMP_ERROR_RSP) && !r_noc_out_rx_burst) begin
            noc_in_rx_wrreq_o      = 1'b1;
            noc_in_rx_bsel_o       = {NOC_BSEL_SIZE{1'b1}};
            noc_in_rx_src_chipid_o = home_chipid_i;
            noc_in_rx_src_modid_o  = HOME_MODID;
            noc_in_rx_trg_chipid_o = home_chipid_i;
            noc_in_rx_trg_modid_o  = HOME_MODID;
            noc_in_rx_mode_o       = MODE_ERROR;
            noc_in_rx_addr_o       = fifo_dataout_addr;
            noc_in_rx_data0_o      = {NOC_DATA_SIZE{1'b0}};
        end
    end


    assign pmp_drop_flit_count_o = r_drop_flit_count;

    assign reg_addr_o = r_reg_addr;


    assign noc_out_tx_burst_o      = fifo_dataout_burst;
    assign noc_out_tx_arq_o        = fifo_dataout_arq;
    assign noc_out_tx_bsel_o       = fifo_dataout_bsel;
    assign noc_out_tx_src_modid_o  = HOME_MODID;
    assign noc_out_tx_trg_modid_o  = mep_pe;
    assign noc_out_tx_src_chipid_o = home_chipid_i;
    assign noc_out_tx_trg_chipid_o = mep_chip;
    assign noc_out_tx_mode_o       = fifo_dataout_mode;
    assign noc_out_tx_addr_o       = mep_addr + pmp_offset;
    assign noc_out_tx_data0_o      = fifo_dataout_data0;
    assign noc_out_tx_data1_o      = fifo_dataout_data1;


    assign noc_in_tx_stall_o = fifo_full;


endmodule