blob: ce4430b5a06a69e2fbf76483cb53613ee6912e59 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// USB Full-Speed Device Interface (usbdev).
//
//
module usbdev (
input clk_i,
input rst_ni,
input clk_usb_48mhz_i, // use usb_ prefix for signals in this clk
// TODO: add a reset signal for the USB-48MHz clock domain here
// Register interface
input tlul_pkg::tl_h2d_t tl_d_i,
output tlul_pkg::tl_d2h_t tl_d_o,
// USB Interface
input cio_usb_dp_i,
output logic cio_usb_dp_o,
output logic cio_usb_dp_en_o,
input cio_usb_dn_i,
output logic cio_usb_dn_o,
output logic cio_usb_dn_en_o,
input cio_usb_sense_i,
output logic cio_usb_pullup_o,
output logic cio_usb_pullup_en_o,
// Interrupts
output logic intr_pkt_received_o, // Packet received
output logic intr_pkt_sent_o, // Packet sent
output logic intr_disconnected_o,
output logic intr_host_lost_o,
output logic intr_link_reset_o,
output logic intr_link_suspend_o,
output logic intr_link_resume_o,
output logic intr_av_empty_o,
output logic intr_rx_full_o,
output logic intr_av_overflow_o
);
import usbdev_reg_pkg::*;
// Could make SramDepth, MaxPktSizeByte, AVFifoDepth and RXFifoDepth
// module parameters but may need to fix register def for the first two
localparam int SramDw = 32; // Places packing bytes to SRAM assume this
localparam int SramDepth = 512; // 2kB, SRAM Width is DW
localparam int MaxPktSizeByte = 64;
localparam int SramAw = $clog2(SramDepth);
localparam int SizeWidth = $clog2(MaxPktSizeByte);
localparam int NBuf = (SramDepth * SramDw) / (MaxPktSizeByte * 8);
localparam int NBufWidth = $clog2(NBuf);
// AV fifo just stores buffer numbers
localparam int AVFifoWidth = NBufWidth;
localparam int AVFifoDepth = 4;
// RX fifo stores buf# + size(0-MaxPktSizeByte) + EP# + Type
localparam int RXFifoWidth = NBufWidth + (1+SizeWidth) + 4 + 1;
localparam int RXFifoDepth = 4;
usbdev_reg2hw_t reg2hw;
usbdev_hw2reg_t hw2reg;
tlul_pkg::tl_h2d_t tl_sram_h2d [1];
tlul_pkg::tl_d2h_t tl_sram_d2h [1];
// Dual-port SRAM Interface: Refer prim_ram_2p_wrapper.sv
logic mem_a_req;
logic mem_a_write;
logic [SramAw-1:0] mem_a_addr;
logic [SramDw-1:0] mem_a_wdata;
logic mem_a_rvalid;
logic [SramDw-1:0] mem_a_rdata;
logic [1:0] mem_a_rerror;
logic usb_mem_b_req;
logic usb_mem_b_write;
logic [SramAw-1:0] usb_mem_b_addr;
logic [SramDw-1:0] usb_mem_b_wdata;
logic [SramDw-1:0] usb_mem_b_rdata;
logic usb_clr_devaddr;
logic event_av_empty, event_av_overflow, event_rx_full;
logic usb_event_link_reset, usb_event_link_suspend, usb_event_link_resume;
logic usb_event_host_lost, usb_event_disconnect;
logic event_link_reset, event_link_suspend, event_link_resume;
logic event_host_lost, event_disconnect;
//=======================================================================
// Receive interface fifos
//
logic av_fifo_wready;
logic event_pkt_received;
logic usbdev_rst_n;
logic usb_av_rvalid, usb_av_rready;
logic usb_rx_wvalid, usb_rx_wready;
logic rx_fifo_rvalid;
logic [AVFifoWidth - 1:0] usb_av_rdata;
logic [RXFifoWidth - 1:0] usb_rx_wdata, rx_rdata;
assign event_av_overflow = reg2hw.avbuffer.qe & (~av_fifo_wready);
assign usbdev_rst_n = rst_ni;
assign hw2reg.usbstat.av_full.d = ~av_fifo_wready;
assign hw2reg.usbstat.rx_empty.d = ~rx_fifo_rvalid;
prim_fifo_async #(
.Width(AVFifoWidth),
.Depth(AVFifoDepth)
) usbdev_avfifo (
.clk_wr_i (clk_i),
.rst_wr_ni (usbdev_rst_n),
.wvalid (reg2hw.avbuffer.qe),
.wready (av_fifo_wready),
.wdata (reg2hw.avbuffer.q),
.wdepth (hw2reg.usbstat.av_depth.d),
.clk_rd_i (clk_usb_48mhz_i),
.rst_rd_ni (usbdev_rst_n), // CDC: rely on it being there a long time
.rvalid (usb_av_rvalid),
.rready (usb_av_rready),
.rdata (usb_av_rdata),
.rdepth () // only using empty
);
prim_fifo_async #(
.Width(RXFifoWidth),
.Depth(RXFifoDepth)
) usbdev_rxfifo (
.clk_wr_i (clk_usb_48mhz_i),
.rst_wr_ni (usbdev_rst_n), // CDC: rely on it being there a long time
.wvalid (usb_rx_wvalid),
.wready (usb_rx_wready),
.wdata (usb_rx_wdata),
.wdepth (),
.clk_rd_i (clk_i),
.rst_rd_ni (usbdev_rst_n),
.rvalid (rx_fifo_rvalid),
.rready (reg2hw.rxfifo.buffer.re),
.rdata (rx_rdata),
.rdepth (hw2reg.usbstat.rx_depth.d)
);
assign hw2reg.rxfifo.ep.d = rx_rdata[16:13];
assign hw2reg.rxfifo.setup.d = rx_rdata[12];
assign hw2reg.rxfifo.size.d = rx_rdata[11:5];
assign hw2reg.rxfifo.buffer.d = rx_rdata[4:0];
assign event_pkt_received = rx_fifo_rvalid;
logic [2:0] unused_re;
assign unused_re = {reg2hw.rxfifo.ep.re, reg2hw.rxfifo.setup.re, reg2hw.rxfifo.size.re};
//======================================================================
// IN (Transmit) interface config
//
logic [NBufWidth - 1:0] usb_in_buf [12];
logic [SizeWidth:0] usb_in_size [12];
logic [3:0] usb_in_endpoint;
logic [11:0] ep_stall, usb_in_rdy;
logic [11:0] clear_rdybit, set_sentbit, update_pend;
logic usb_out_clear_rdy, out_clear_rdy, usb_set_sent, set_sent;
logic [11:0] enable_setup, enable_out;
assign enable_setup = {
reg2hw.rxenable.setup11.q, reg2hw.rxenable.setup10.q,
reg2hw.rxenable.setup9.q, reg2hw.rxenable.setup8.q,
reg2hw.rxenable.setup7.q, reg2hw.rxenable.setup6.q,
reg2hw.rxenable.setup5.q, reg2hw.rxenable.setup4.q,
reg2hw.rxenable.setup3.q, reg2hw.rxenable.setup2.q,
reg2hw.rxenable.setup1.q, reg2hw.rxenable.setup0.q};
assign enable_out = {
reg2hw.rxenable.out11.q, reg2hw.rxenable.out10.q,
reg2hw.rxenable.out9.q, reg2hw.rxenable.out8.q,
reg2hw.rxenable.out7.q, reg2hw.rxenable.out6.q,
reg2hw.rxenable.out5.q, reg2hw.rxenable.out4.q,
reg2hw.rxenable.out3.q, reg2hw.rxenable.out2.q,
reg2hw.rxenable.out1.q, reg2hw.rxenable.out0.q};
// STALL for both directions
assign ep_stall = {
reg2hw.stall.stall11.q, reg2hw.stall.stall10.q,
reg2hw.stall.stall9.q, reg2hw.stall.stall8.q,
reg2hw.stall.stall7.q, reg2hw.stall.stall6.q,
reg2hw.stall.stall5.q, reg2hw.stall.stall4.q,
reg2hw.stall.stall3.q, reg2hw.stall.stall2.q,
reg2hw.stall.stall1.q, reg2hw.stall.stall0.q};
// Clock domain crossing fifo for ready bit covers others so assigns are ok
assign usb_in_buf[0] = reg2hw.configin0.buffer0.q;
assign usb_in_size[0] = reg2hw.configin0.size0.q;
assign usb_in_buf[1] = reg2hw.configin1.buffer1.q;
assign usb_in_size[1] = reg2hw.configin1.size1.q;
assign usb_in_buf[2] = reg2hw.configin2.buffer2.q;
assign usb_in_size[2] = reg2hw.configin2.size2.q;
assign usb_in_buf[3] = reg2hw.configin3.buffer3.q;
assign usb_in_size[3] = reg2hw.configin3.size3.q;
assign usb_in_buf[4] = reg2hw.configin4.buffer4.q;
assign usb_in_size[4] = reg2hw.configin4.size4.q;
assign usb_in_buf[5] = reg2hw.configin5.buffer5.q;
assign usb_in_size[5] = reg2hw.configin5.size5.q;
assign usb_in_buf[6] = reg2hw.configin6.buffer6.q;
assign usb_in_size[6] = reg2hw.configin6.size6.q;
assign usb_in_buf[7] = reg2hw.configin7.buffer7.q;
assign usb_in_size[7] = reg2hw.configin7.size7.q;
assign usb_in_buf[8] = reg2hw.configin8.buffer8.q;
assign usb_in_size[8] = reg2hw.configin8.size8.q;
assign usb_in_buf[9] = reg2hw.configin9.buffer9.q;
assign usb_in_size[9] = reg2hw.configin9.size9.q;
assign usb_in_buf[10] = reg2hw.configin10.buffer10.q;
assign usb_in_size[10] = reg2hw.configin10.size10.q;
assign usb_in_buf[11] = reg2hw.configin11.buffer11.q;
assign usb_in_size[11] = reg2hw.configin11.size11.q;
prim_flop_2sync #(
.Width(12)
) usbdev_rdysync (
.clk_i (clk_usb_48mhz_i),
.rst_ni (rst_ni),
.d( {reg2hw.configin11.rdy11.q, reg2hw.configin10.rdy10.q,
reg2hw.configin9.rdy9.q, reg2hw.configin8.rdy8.q,
reg2hw.configin7.rdy7.q, reg2hw.configin6.rdy6.q,
reg2hw.configin5.rdy5.q, reg2hw.configin4.rdy4.q,
reg2hw.configin3.rdy3.q, reg2hw.configin2.rdy2.q,
reg2hw.configin1.rdy1.q, reg2hw.configin0.rdy0.q }),
.q(usb_in_rdy)
);
// Clear of ready and set of sent is a pulse in USB clock domain
// but needs to ensure register bit is cleared/set in TLUL domain
// usbdev_pulsesync takes pulse in clk_src to pulse in clk_dst
prim_pulse_sync usbdev_setsent (
.clk_src_i (clk_usb_48mhz_i),
.clk_dst_i (clk_i),
.rst_src_ni (rst_ni),
.rst_dst_ni (rst_ni),
.src_pulse_i (usb_set_sent),
.dst_pulse_o (set_sent)
);
always_comb begin
set_sentbit = 12'b0;
if (set_sent) begin
// syncronization of set_sent ensures usb_endpoint is stable
set_sentbit[usb_in_endpoint] = 1; // lint: usb_in_endpoint range was checked
end
end
assign {hw2reg.in_sent.sent11.de, hw2reg.in_sent.sent10.de,
hw2reg.in_sent.sent9.de, hw2reg.in_sent.sent8.de,
hw2reg.in_sent.sent7.de, hw2reg.in_sent.sent6.de,
hw2reg.in_sent.sent5.de, hw2reg.in_sent.sent4.de,
hw2reg.in_sent.sent3.de, hw2reg.in_sent.sent2.de,
hw2reg.in_sent.sent1.de, hw2reg.in_sent.sent0.de } = set_sentbit;
assign {hw2reg.in_sent.sent11.d, hw2reg.in_sent.sent10.d,
hw2reg.in_sent.sent9.d, hw2reg.in_sent.sent8.d,
hw2reg.in_sent.sent7.d, hw2reg.in_sent.sent6.d,
hw2reg.in_sent.sent5.d, hw2reg.in_sent.sent4.d,
hw2reg.in_sent.sent3.d, hw2reg.in_sent.sent2.d,
hw2reg.in_sent.sent1.d, hw2reg.in_sent.sent0.d } = 12'hfff;
prim_pulse_sync usbdev_outrdyclr (
.clk_src_i (clk_usb_48mhz_i),
.clk_dst_i (clk_i),
.rst_src_ni (rst_ni),
.rst_dst_ni (rst_ni),
.src_pulse_i (usb_out_clear_rdy),
.dst_pulse_o (out_clear_rdy)
);
logic event_link_reset_q;
always_ff @(posedge clk_usb_48mhz_i or negedge rst_ni) begin
if (!rst_ni) begin
event_link_reset_q <= 0;
end else begin
event_link_reset_q <= event_link_reset;
end
end
always_comb begin
clear_rdybit = 12'b0;
update_pend = 12'b0;
if (event_link_reset && !event_link_reset_q) begin
clear_rdybit = 12'hfff;
update_pend = 12'hfff;
end else begin
clear_rdybit[usb_in_endpoint] = set_sent | out_clear_rdy; // lint: usb_in_endpoint range was checked
update_pend[usb_in_endpoint] = out_clear_rdy; // lint: usb_in_endpoint range was checked
end
end
assign {hw2reg.configin11.rdy11.de, hw2reg.configin10.rdy10.de,
hw2reg.configin9.rdy9.de, hw2reg.configin8.rdy8.de,
hw2reg.configin7.rdy7.de, hw2reg.configin6.rdy6.de,
hw2reg.configin5.rdy5.de, hw2reg.configin4.rdy4.de,
hw2reg.configin3.rdy3.de, hw2reg.configin2.rdy2.de,
hw2reg.configin1.rdy1.de, hw2reg.configin0.rdy0.de } = clear_rdybit;
assign {hw2reg.configin11.rdy11.d, hw2reg.configin10.rdy10.d,
hw2reg.configin9.rdy9.d, hw2reg.configin8.rdy8.d,
hw2reg.configin7.rdy7.d, hw2reg.configin6.rdy6.d,
hw2reg.configin5.rdy5.d, hw2reg.configin4.rdy4.d,
hw2reg.configin3.rdy3.d, hw2reg.configin2.rdy2.d,
hw2reg.configin1.rdy1.d, hw2reg.configin0.rdy0.d } = 12'b0;
// Update the pending bit by copying the ready bit that is about to clear
assign {hw2reg.configin11.pend11.de, hw2reg.configin10.pend10.de,
hw2reg.configin9.pend9.de, hw2reg.configin8.pend8.de,
hw2reg.configin7.pend7.de, hw2reg.configin6.pend6.de,
hw2reg.configin5.pend5.de, hw2reg.configin4.pend4.de,
hw2reg.configin3.pend3.de, hw2reg.configin2.pend2.de,
hw2reg.configin1.pend1.de, hw2reg.configin0.pend0.de } = update_pend;
assign hw2reg.configin11.pend11.d = reg2hw.configin11.rdy11.q | reg2hw.configin11.pend11.q;
assign hw2reg.configin10.pend10.d = reg2hw.configin10.rdy10.q | reg2hw.configin10.pend10.q;
assign hw2reg.configin9.pend9.d = reg2hw.configin9.rdy9.q | reg2hw.configin9.pend9.q;
assign hw2reg.configin8.pend8.d = reg2hw.configin8.rdy8.q | reg2hw.configin8.pend8.q;
assign hw2reg.configin7.pend7.d = reg2hw.configin7.rdy7.q | reg2hw.configin7.pend7.q;
assign hw2reg.configin6.pend6.d = reg2hw.configin6.rdy6.q | reg2hw.configin6.pend6.q;
assign hw2reg.configin5.pend5.d = reg2hw.configin5.rdy5.q | reg2hw.configin5.pend5.q;
assign hw2reg.configin4.pend4.d = reg2hw.configin4.rdy4.q | reg2hw.configin4.pend4.q;
assign hw2reg.configin3.pend3.d = reg2hw.configin3.rdy3.q | reg2hw.configin3.pend3.q;
assign hw2reg.configin2.pend2.d = reg2hw.configin2.rdy2.q | reg2hw.configin2.pend2.q;
assign hw2reg.configin1.pend1.d = reg2hw.configin1.rdy1.q | reg2hw.configin1.pend1.q;
assign hw2reg.configin0.pend0.d = reg2hw.configin0.rdy0.q | reg2hw.configin0.pend0.q;
//======================================================================
// USB interface -- everything is in USB clock domain
assign hw2reg.usbstat.usb_sense.d = cio_usb_sense_i;
usbdev_usbif #(
.AVFifoWidth (AVFifoWidth),
.RXFifoWidth (RXFifoWidth),
.MaxPktSizeByte (MaxPktSizeByte),
.NBuf (NBuf),
.SramAw (SramAw)
) usbdev_impl (
.clk_48mhz_i (clk_usb_48mhz_i),
.rst_ni (usbdev_rst_n),
// Pins
.usb_dp_i (cio_usb_dp_i),
.usb_dp_o (cio_usb_dp_o),
.usb_dp_en_o (cio_usb_dp_en_o),
.usb_dn_i (cio_usb_dn_i),
.usb_dn_o (cio_usb_dn_o),
.usb_dn_en_o (cio_usb_dn_en_o),
.usb_sense_i (cio_usb_sense_i),
.usb_pullup_o (cio_usb_pullup_o),
.usb_pullup_en_o (cio_usb_pullup_en_o),
// receive side
.rx_setup_i (enable_setup),
.rx_out_i (enable_out),
.rx_stall_i (ep_stall),
.av_rvalid_i (usb_av_rvalid),
.av_rready_o (usb_av_rready),
.av_rdata_i (usb_av_rdata),
.event_av_empty_o(event_av_empty),
.rx_wvalid_o (usb_rx_wvalid),
.rx_wready_i (usb_rx_wready),
.rx_wdata_o (usb_rx_wdata),
.event_rx_full_o (event_rx_full),
.out_clear_rdy_o (usb_out_clear_rdy),
.out_endpoint_o (),
// transmit side
.in_buf_i (usb_in_buf[usb_in_endpoint]), // lint: usb_in_endpoint range was checked
.in_size_i (usb_in_size[usb_in_endpoint]), // lint: usb_in_endpoint range was checked
.in_stall_i (ep_stall),
.in_rdy_i (usb_in_rdy),
.set_sent_o (usb_set_sent),
.in_endpoint_o (usb_in_endpoint),
// memory
.mem_req_o (usb_mem_b_req),
.mem_write_o (usb_mem_b_write),
.mem_addr_o (usb_mem_b_addr),
.mem_wdata_o (usb_mem_b_wdata),
.mem_rdata_i (usb_mem_b_rdata),
// control
.enable_i (reg2hw.usbctrl.enable.q),
.devaddr_i (reg2hw.usbctrl.device_address.q),
.clr_devaddr_o (usb_clr_devaddr),
// status
.frame_o (hw2reg.usbstat.frame.d),
.link_state_o (hw2reg.usbstat.link_state.d),
.link_disconnect_o(usb_event_disconnect),
.link_reset_o (usb_event_link_reset),
.link_suspend_o (usb_event_link_suspend),
.link_resume_o (usb_event_link_resume),
.host_lost_o (usb_event_host_lost)
);
// CDC for event signals (arguably they are there for a long time so would be ok)
// Just want a pulse to ensure only one interrupt for an event
usbdev_flop_2syncpulse #(.Width(4)) syncevent (
.clk_i (clk_i),
.rst_ni (rst_ni),
.d ({usb_event_disconnect, usb_event_link_reset, usb_event_link_suspend,
usb_event_host_lost}),
.q ({event_disconnect, event_link_reset, event_link_suspend, event_host_lost})
);
// Resume is a single pulse so needs pulsesync
prim_pulse_sync usbdev_resume (
.clk_src_i (clk_usb_48mhz_i),
.clk_dst_i (clk_i),
.rst_src_ni (rst_ni),
.rst_dst_ni (rst_ni),
.src_pulse_i (usb_event_link_resume),
.dst_pulse_o (event_link_resume)
);
assign hw2reg.usbstat.host_lost.d = event_host_lost;
// resets etc cause the device address to clear
prim_pulse_sync usbdev_devclr (
.clk_src_i (clk_usb_48mhz_i),
.clk_dst_i (clk_i),
.rst_src_ni (rst_ni),
.rst_dst_ni (rst_ni),
.src_pulse_i (usb_clr_devaddr),
.dst_pulse_o (hw2reg.usbctrl.device_address.de)
);
assign hw2reg.usbctrl.device_address.d = '0;
//======================================================================
logic unused_mem_a_rerror_d;
tlul_adapter_sram #(
.SramAw(SramAw)
) u_tlul2sram (
.clk_i,
.rst_ni,
.tl_i (tl_sram_h2d [0]),
.tl_o (tl_sram_d2h [0]),
.req_o (mem_a_req),
.gnt_i (mem_a_req), //Always grant when request
.we_o (mem_a_write),
.addr_o (mem_a_addr),
.wdata_o (mem_a_wdata),
.wmask_o (), // Not used
.rdata_i (mem_a_rdata),
.rvalid_i (mem_a_rvalid),
.rerror_i (mem_a_rerror)
);
assign unused_mem_a_rerror_d = mem_a_rerror[1] ; // Only uncorrectable error
// SRAM Wrapper
prim_ram_2p_async_adv #(
.Depth (SramDepth),
.Width (SramDw), // 32 x 512 --> 2kB
.CfgW (8),
.EnableECC (1), // No Protection
.EnableParity (0),
.EnableInputPipeline (0),
.EnableOutputPipeline(0),
.MemT ("REGISTER")
) u_memory_2p (
.clk_a_i (clk_i),
.clk_b_i (clk_usb_48mhz_i),
.rst_ni (rst_ni),
.a_req_i (mem_a_req),
.a_write_i (mem_a_write),
.a_addr_i (mem_a_addr),
.a_wdata_i (mem_a_wdata),
.a_rvalid_o (mem_a_rvalid),
.a_rdata_o (mem_a_rdata),
.a_rerror_o (mem_a_rerror),
.b_req_i (usb_mem_b_req),
.b_write_i (usb_mem_b_write),
.b_addr_i (usb_mem_b_addr),
.b_wdata_i (usb_mem_b_wdata),
.b_rvalid_o (),
.b_rdata_o (usb_mem_b_rdata),
.b_rerror_o (),
.cfg_i ('0)
);
// Register module
usbdev_reg_top u_reg (
.clk_i,
.rst_ni,
.tl_i (tl_d_i),
.tl_o (tl_d_o),
.tl_win_o (tl_sram_h2d),
.tl_win_i (tl_sram_d2h),
.reg2hw,
.hw2reg,
.devmode_i (1'b1)
);
prim_intr_hw #(.Width(1)) intr_hw_pkt_received (
.event_intr_i (event_pkt_received),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.pkt_received.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.pkt_received.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.pkt_received.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.pkt_received.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.pkt_received.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.pkt_received.d),
.intr_o (intr_pkt_received_o)
);
prim_intr_hw #(.Width(1)) intr_hw_pkt_sent (
.event_intr_i (set_sent),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.pkt_sent.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.pkt_sent.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.pkt_sent.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.pkt_sent.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.pkt_sent.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.pkt_sent.d),
.intr_o (intr_pkt_sent_o)
);
prim_intr_hw #(.Width(1)) intr_disconnected (
.event_intr_i (event_disconnect),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.disconnected.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.disconnected.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.disconnected.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.disconnected.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.disconnected.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.disconnected.d),
.intr_o (intr_disconnected_o)
);
prim_intr_hw #(.Width(1)) intr_host_lost (
.event_intr_i (event_host_lost),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.host_lost.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.host_lost.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.host_lost.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.host_lost.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.host_lost.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.host_lost.d),
.intr_o (intr_host_lost_o)
);
prim_intr_hw #(.Width(1)) intr_link_reset (
.event_intr_i (event_link_reset),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.link_reset.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.link_reset.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.link_reset.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.link_reset.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.link_reset.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.link_reset.d),
.intr_o (intr_link_reset_o)
);
prim_intr_hw #(.Width(1)) intr_link_suspend (
.event_intr_i (event_link_suspend),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.link_suspend.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.link_suspend.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.link_suspend.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.link_suspend.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.link_suspend.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.link_suspend.d),
.intr_o (intr_link_suspend_o)
);
prim_intr_hw #(.Width(1)) intr_link_resume (
.event_intr_i (event_link_resume),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.link_resume.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.link_resume.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.link_resume.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.link_resume.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.link_resume.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.link_resume.d),
.intr_o (intr_link_resume_o)
);
prim_intr_hw #(.Width(1)) intr_av_empty (
.event_intr_i (event_av_empty),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.av_empty.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.av_empty.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.av_empty.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.av_empty.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.av_empty.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.av_empty.d),
.intr_o (intr_av_empty_o)
);
prim_intr_hw #(.Width(1)) intr_rx_full (
.event_intr_i (event_rx_full),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_full.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.rx_full.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.rx_full.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.rx_full.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.rx_full.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.rx_full.d),
.intr_o (intr_rx_full_o)
);
prim_intr_hw #(.Width(1)) intr_av_overflow (
.event_intr_i (event_av_overflow),
.reg2hw_intr_enable_q_i (reg2hw.intr_enable.av_overflow.q),
.reg2hw_intr_test_q_i (reg2hw.intr_test.av_overflow.q),
.reg2hw_intr_test_qe_i (reg2hw.intr_test.av_overflow.qe),
.reg2hw_intr_state_q_i (reg2hw.intr_state.av_overflow.q),
.hw2reg_intr_state_de_o (hw2reg.intr_state.av_overflow.de),
.hw2reg_intr_state_d_o (hw2reg.intr_state.av_overflow.d),
.intr_o (intr_av_overflow_o)
);
endmodule