Browse Source

projects/riscv_usb: Move the USB stuff to a separate module

Makes the top level cleaner and it's pretty much common to any
top level config you'd use.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Sylvain Munaut 4 years ago
parent
commit
fc12f0de48
3 changed files with 160 additions and 81 deletions
  1. 1 0
      projects/riscv_usb/Makefile
  2. 142 0
      projects/riscv_usb/rtl/soc_usb.v
  3. 17 81
      projects/riscv_usb/rtl/top.v

+ 1 - 0
projects/riscv_usb/Makefile

@@ -10,6 +10,7 @@ PROJ_RTL_SRCS := $(addprefix rtl/, \
 	soc_picorv32_base.v \
 	soc_picorv32_bridge.v \
 	soc_spram.v \
+	soc_usb.v \
 	sysmgr.v \
 )
 PROJ_SIM_SRCS := $(addprefix sim/, \

+ 142 - 0
projects/riscv_usb/rtl/soc_usb.v

@@ -0,0 +1,142 @@
+/*
+ * soc_usb.v
+ *
+ * vim: ts=4 sw=4
+ *
+ * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
+ * SPDX-License-Identifier: CERN-OHL-P-2.0
+ */
+
+`default_nettype none
+
+module soc_usb #(
+	parameter integer DW = 32
+)(
+	// USB
+	inout  wire usb_dp,
+	inout  wire usb_dn,
+	output wire usb_pu,
+
+	// Wishbone slave
+	input  wire [  11:0] wb_addr,
+	output wire [DW-1:0] wb_rdata,
+	input  wire [DW-1:0] wb_wdata,
+	input  wire          wb_we,
+	input  wire    [1:0] wb_cyc,
+	output wire    [1:0] wb_ack,
+
+	// Clock / Reset
+	input  wire clk_sys,
+	input  wire clk_48m,
+	input  wire rst
+);
+
+	// Signals
+	// -------
+
+	// Bus OR
+	wire [DW-1:0] wb_rdata_i[0:1];
+
+	// Wishbone in 48 MHz domain
+	wire [11:0] ub_addr;
+	wire [15:0] ub_wdata;
+	wire [15:0] ub_rdata;
+	wire        ub_cyc;
+	wire        ub_we;
+	wire        ub_ack;
+
+	// EP Buffer
+	wire [ 8:0] ep_tx_addr_0;
+	wire [31:0] ep_tx_data_0;
+	wire        ep_tx_we_0;
+
+	wire [ 8:0] ep_rx_addr_0;
+	wire [31:0] ep_rx_data_1;
+	wire        ep_rx_re_0;
+
+	reg ack_ep;
+
+
+	// Cross-clock
+	// -----------
+		// Bring control reg wishbone to 48 MHz domain
+
+	xclk_wb #(
+		.DW(16),
+		.AW(12)
+	)  wb_48m_xclk_I (
+		.s_addr  (wb_addr[11:0]),
+		.s_wdata (wb_wdata[15:0]),
+		.s_rdata (wb_rdata_i[0][15:0]),
+		.s_cyc   (wb_cyc[0]),
+		.s_ack   (wb_ack[0]),
+		.s_we    (wb_we),
+		.s_clk   (clk_sys),
+		.m_addr  (ub_addr),
+		.m_wdata (ub_wdata),
+		.m_rdata (ub_rdata),
+		.m_cyc   (ub_cyc),
+		.m_ack   (ub_ack),
+		.m_we    (ub_we),
+		.m_clk   (clk_48m),
+		.rst     (rst)
+	);
+
+	if (DW != 16)
+		assign wb_rdata_i[0][DW-1:16] = 0;
+
+
+	// Core
+	// ----
+
+	usb #(
+		.EPDW(32)
+	) usb_I (
+		.pad_dp       (usb_dp),
+		.pad_dn       (usb_dn),
+		.pad_pu       (usb_pu),
+		.ep_tx_addr_0 (ep_tx_addr_0),
+		.ep_tx_data_0 (ep_tx_data_0),
+		.ep_tx_we_0   (ep_tx_we_0),
+		.ep_rx_addr_0 (ep_rx_addr_0),
+		.ep_rx_data_1 (ep_rx_data_1),
+		.ep_rx_re_0   (ep_rx_re_0),
+		.ep_clk       (clk_sys),
+		.wb_addr      (ub_addr),
+		.wb_rdata     (ub_rdata),
+		.wb_wdata     (ub_wdata),
+		.wb_we        (ub_we),
+		.wb_cyc       (ub_cyc),
+		.wb_ack       (ub_ack),
+		.clk          (clk_48m),
+		.rst          (rst)
+	);
+
+
+	// EP data
+	// -------
+
+	assign ep_tx_addr_0 = wb_addr[8:0];
+	assign ep_rx_addr_0 = wb_addr[8:0];
+
+	assign ep_tx_data_0 = wb_wdata;
+	assign wb_rdata_i[1] = ack_ep ? ep_rx_data_1 : 32'h00000000;
+
+	assign ep_tx_we_0 = wb_cyc[1] & wb_we & ~ack_ep;
+	assign ep_rx_re_0 = 1'b1;
+
+	assign wb_ack[1] = ack_ep;
+
+	always @(posedge clk_sys or posedge rst)
+		if (rst)
+			ack_ep <= 1'b0;
+		else
+			ack_ep <= wb_cyc[1] & ~ack_ep;
+
+
+	// Bus read data
+	// -------------
+
+	assign wb_rdata = wb_rdata_i[0] | wb_rdata_i[1];
+
+endmodule // soc_usb

+ 17 - 81
projects/riscv_usb/rtl/top.v

@@ -63,24 +63,6 @@ module top (
 	wire             wb_we;
 	wire [WB_N -1:0] wb_ack;
 
-	// USB Core
-		// EP Buffer
-	wire [ 8:0] ep_tx_addr_0;
-	wire [31:0] ep_tx_data_0;
-	wire ep_tx_we_0;
-
-	wire [ 8:0] ep_rx_addr_0;
-	wire [31:0] ep_rx_data_1;
-	wire ep_rx_re_0;
-
-		// Bus interface
-	wire [11:0] ub_addr;
-	wire [15:0] ub_wdata;
-	wire [15:0] ub_rdata;
-	wire ub_cyc;
-	wire ub_we;
-	wire ub_ack;
-
 	// WarmBoot
 	reg boot_now;
 	reg [1:0] boot_sel;
@@ -187,73 +169,27 @@ module top (
 	);
 
 
-	// USB Core
-	// --------
+	// USB [4 & 5]
+	// ---
 
-	// Core
-	usb #(
-		.EPDW(32)
+	soc_usb #(
+		.DW(WB_DW)
 	) usb_I (
-		.pad_dp(usb_dp),
-		.pad_dn(usb_dn),
-		.pad_pu(usb_pu),
-		.ep_tx_addr_0(ep_tx_addr_0),
-		.ep_tx_data_0(ep_tx_data_0),
-		.ep_tx_we_0(ep_tx_we_0),
-		.ep_rx_addr_0(ep_rx_addr_0),
-		.ep_rx_data_1(ep_rx_data_1),
-		.ep_rx_re_0(ep_rx_re_0),
-		.ep_clk(clk_24m),
-		.wb_addr(ub_addr),
-		.wb_rdata(ub_rdata),
-		.wb_wdata(ub_wdata),
-		.wb_we(ub_we),
-		.wb_cyc(ub_cyc),
-		.wb_ack(ub_ack),
-		.clk(clk_48m),
-		.rst(rst)
-	);
-
-	// Cross clock bridge
-	xclk_wb #(
-		.DW(16),
-		.AW(12)
-	)  wb_48m_xclk_I (
-		.s_addr(wb_addr[11:0]),
-		.s_wdata(wb_wdata[15:0]),
-		.s_rdata(wb_rdata[4][15:0]),
-		.s_cyc(wb_cyc[4]),
-		.s_ack(wb_ack[4]),
-		.s_we(wb_we),
-		.s_clk(clk_24m),
-		.m_addr(ub_addr),
-		.m_wdata(ub_wdata),
-		.m_rdata(ub_rdata),
-		.m_cyc(ub_cyc),
-		.m_ack(ub_ack),
-		.m_we(ub_we),
-		.m_clk(clk_48m),
-		.rst(rst)
+		.usb_dp   (usb_dp),
+		.usb_dn   (usb_dn),
+		.usb_pu   (usb_pu),
+		.wb_addr  (wb_addr[11:0]),
+		.wb_rdata (wb_rdata[4]),
+		.wb_wdata (wb_wdata),
+		.wb_we    (wb_we),
+		.wb_cyc   (wb_cyc[5:4]),
+		.wb_ack   (wb_ack[5:4]),
+		.clk_sys  (clk_24m),
+		.clk_48m  (clk_48m),
+		.rst      (rst)
 	);
 
-	assign wb_rdata[4][31:16] = 16'h0000;
-
-	// EP buffer interface
-	reg wb_ack_ep;
-
-	always @(posedge clk_24m)
-		wb_ack_ep <= wb_cyc[5] & ~wb_ack_ep;
-
-	assign wb_ack[5] = wb_ack_ep;
-
-	assign ep_tx_addr_0 = wb_addr[8:0];
-	assign ep_tx_data_0 = wb_wdata;
-	assign ep_tx_we_0   = wb_cyc[5] & ~wb_ack[5] & wb_we;
-
-	assign ep_rx_addr_0 = wb_addr[8:0];
-	assign ep_rx_re_0   = 1'b1;
-
-	assign wb_rdata[5] = wb_cyc[5] ? ep_rx_data_1 : 32'h00000000;
+	assign wb_rdata[5] = 0;
 
 
 	// Warm Boot