/* * ut_top.v * * vim: ts=4 sw=4 * * Copyright (C) 2022 Sylvain Munaut * SPDX-License-Identifier: CERN-OHL-P-2.0 */ `default_nettype none module ut_top ( // USB tap input wire tap_dp, input wire tap_dn, // Memory interface output wire [23:0] mi_addr, output wire [ 6:0] mi_len, output wire mi_rw, output wire mi_valid, input wire mi_ready, output wire [7:0] mi_wdata, input wire mi_wack, input wire mi_wlast, input wire [7:0] mi_rdata, input wire mi_rstb, input wire mi_rlast, // DMA access to USB EP output wire dma_req, input wire dma_gnt, output wire [15:0] dma_addr, output wire [31:0] dma_data, output wire dma_we, // Wishbone input wire [3:0] wb_addr, output reg [31:0] wb_rdata, input wire [31:0] wb_wdata, input wire wb_we, input wire wb_cyc, output reg wb_ack, // Clock / Reset input wire clk_1x, input wire clk_2x, input wire rst ); // Signals // ------- // Bus interface wire bus_clr_rd; wire bus_clr_wr; wire [31:0] bus_cap_rdata; reg bus_cap_we_csr; wire [31:0] bus_dmawr_rdata; reg bus_dmawr_we_csr; reg bus_dmawr_we_desc_in; reg bus_dmawr_re_desc_out; wire [31:0] bus_dmard_rdata; reg bus_dmard_we_cmd_lo; reg bus_dmard_we_cmd_hi; // Memory interfaces // Port 0 ( Write Only ) wire [23:0] mi0_addr; wire [ 6:0] mi0_len; wire mi0_valid; wire mi0_ready; wire [7:0] mi0_wdata; wire mi0_wack; wire mi0_wlast; // Port 1 ( Read Only ) wire [23:0] mi1_addr; wire [ 6:0] mi1_len; wire mi1_valid; wire mi1_ready; wire [7:0] mi1_rdata; wire mi1_rstb; wire mi1_rlast; // Stream wire [7:0] stream_data; wire stream_stb; // Bus interface // ------------- // Ack always @(posedge clk_1x) wb_ack <= wb_cyc & ~wb_ack; // Bus clears assign bus_clr_rd = ~wb_cyc | wb_ack | wb_we; assign bus_clr_wr = ~wb_cyc | wb_ack | ~wb_we; // Read mux always @(posedge clk_1x) if (bus_clr_rd) wb_rdata <= 32'h00000000; else casez (wb_addr) 4'b00zz: wb_rdata <= bus_cap_rdata; 4'b10zz: wb_rdata <= bus_dmawr_rdata; 4'b11zz: wb_rdata <= bus_dmard_rdata; default: wb_rdata <= 32'hxxxxxxxx; endcase // Write Strobes always @(posedge clk_1x) if (bus_clr_wr) begin bus_cap_we_csr <= 1'b0; bus_dmawr_we_csr <= 1'b0; bus_dmawr_we_desc_in <= 1'b0; bus_dmard_we_cmd_lo <= 1'b0; bus_dmard_we_cmd_hi <= 1'b0; end else begin bus_cap_we_csr <= (wb_addr == 4'b0000); bus_dmawr_we_csr <= (wb_addr == 4'b1000); bus_dmawr_we_desc_in <= (wb_addr == 4'b1010); bus_dmard_we_cmd_lo <= (wb_addr == 4'b1110); bus_dmard_we_cmd_hi <= (wb_addr == 4'b1111); end // Read Strobes always @(posedge clk_1x) if (bus_clr_rd) begin bus_dmawr_re_desc_out <= 1'b0; end else begin bus_dmawr_re_desc_out <= (wb_addr == 4'b1011); end // Memory arbiter // -------------- memif_arb #( .AW(24), .DW(8), .WRITE_DISABLE(2'b10) ) arb_I ( .u_addr (mi_addr), .u_len (mi_len), .u_rw (mi_rw), .u_valid (mi_valid), .u_ready (mi_ready), .u_wdata (mi_wdata), .u_wack (mi_wack), .u_wlast (mi_wlast), .u_rdata (mi_rdata), .u_rstb (mi_rstb), .u_rlast (mi_rlast), .d0_addr (mi0_addr), .d0_len (mi0_len), .d0_rw (1'b0), .d0_valid (mi0_valid), .d0_ready (mi0_ready), .d0_wdata (mi0_wdata), .d0_wack (mi0_wack), .d0_wlast (mi0_wlast), .d0_rdata (), .d0_rstb (), .d0_rlast (), .d1_addr (mi1_addr), .d1_len (mi1_len), .d1_rw (1'b1), .d1_valid (mi1_valid), .d1_ready (mi1_ready), .d1_wdata (8'h0), .d1_wack (), .d1_wlast (), .d1_rdata (mi1_rdata), .d1_rstb (mi1_rstb), .d1_rlast (mi1_rlast), .clk (clk_1x), .rst (rst) ); // USB Packet Receiver // ------------------- ut_pkt pkt_I ( .bus_rdata (bus_cap_rdata), .bus_wdata (wb_wdata), .bus_we_csr (bus_cap_we_csr), .tap_dp (tap_dp), .tap_dn (tap_dn), .stream_data (stream_data), .stream_stb (stream_stb), .clk_1x (clk_1x), .clk_2x (clk_2x), .rst (rst) ); // DMA Write (FIFO -> Mem) // --------- ut_dma_wr dma_wr_I ( .bus_addr (wb_addr[1:0]), .bus_rdata (bus_dmawr_rdata), .bus_wdata (wb_wdata), .bus_we_csr (bus_dmawr_we_csr), .bus_we_desc_in (bus_dmawr_we_desc_in), .bus_re_desc_out (bus_dmawr_re_desc_out), .stream_data (stream_data), .stream_stb (stream_stb), .mi_addr (mi0_addr), .mi_len (mi0_len), .mi_valid (mi0_valid), .mi_ready (mi0_ready), .mi_wdata (mi0_wdata), .mi_wack (mi0_wack), .mi_wlast (mi0_wlast), .clk (clk_1x), .rst (rst) ); // DMA Read (Mem -> USB) // -------- ut_dma_rd dma_rd_I ( .bus_rdata (bus_dmard_rdata), .bus_wdata (wb_wdata), .bus_we_cmd_lo (bus_dmard_we_cmd_lo), .bus_we_cmd_hi (bus_dmard_we_cmd_hi), .mi_addr (mi1_addr), .mi_len (mi1_len), .mi_valid (mi1_valid), .mi_ready (mi1_ready), .mi_rdata (mi1_rdata), .mi_rstb (mi1_rstb), .mi_rlast (mi1_rlast), .dma_req (dma_req), .dma_gnt (dma_gnt), .dma_addr (dma_addr), .dma_data (dma_data), .dma_we (dma_we), .clk (clk_1x), .rst (rst) ); endmodule // ut_top