488 lines
13 KiB
Systemverilog
488 lines
13 KiB
Systemverilog
`timescale 1ns/1ps
|
|
|
|
module genesys2_rocket_top (
|
|
input wire sysclk_p,
|
|
input wire sysclk_n,
|
|
input wire cpu_resetn,
|
|
// Digilent labels these from the PC/FTDI side: TX_IN is FPGA RX, RX_OUT is FPGA TX.
|
|
input wire uart_tx_in,
|
|
output wire uart_rx_out,
|
|
// External RF PMOD input. The connector side is 3.3 V; XDC sets the FPGA I/O standard.
|
|
input wire rf_clk_pmod,
|
|
input wire [3:0] rf_data_pmod,
|
|
output wire pmod_spi_sck,
|
|
output wire pmod_spi_csn,
|
|
inout wire [3:0] pmod_spi_dq,
|
|
input wire pmod_irq,
|
|
output wire gps_pps,
|
|
inout wire [3:0] qspi_d,
|
|
output wire qspi_csn,
|
|
output wire [7:0] led
|
|
);
|
|
wire sysclk_200;
|
|
wire fabric_clk;
|
|
wire gps_acq_clk_gen;
|
|
wire gps_trck_clk_gen;
|
|
wire gps_rf_clk_selected;
|
|
wire [3:0] gps_rf_data_selected;
|
|
wire gps_rf_ready;
|
|
wire fabric_clkfb;
|
|
wire fabric_clkfb_buf;
|
|
wire gps_ref_clkfb;
|
|
wire gps_ref_clkfb_buf;
|
|
wire gps_ref_clk_gen;
|
|
wire pll_gps_ref_clk;
|
|
wire gps_ref_pll_locked;
|
|
wire gps_clkfb;
|
|
wire gps_clkfb_buf;
|
|
wire pll_gps_acq_clk;
|
|
wire pll_fabric_clk;
|
|
wire pll_gps_trck_clk;
|
|
wire fabric_pll_locked;
|
|
wire gps_domain_pll_locked;
|
|
wire gps_clock_locked = gps_ref_pll_locked & gps_domain_pll_locked;
|
|
wire board_reset = ~cpu_resetn;
|
|
|
|
|
|
IBUFDS #(
|
|
.DIFF_TERM("FALSE"),
|
|
.IBUF_LOW_PWR("FALSE")
|
|
) u_sysclk_ibufds (
|
|
.I(sysclk_p),
|
|
.IB(sysclk_n),
|
|
.O(sysclk_200)
|
|
);
|
|
|
|
MMCME2_ADV #(
|
|
.BANDWIDTH("OPTIMIZED"),
|
|
.CLKFBOUT_MULT_F(5.000),
|
|
.CLKFBOUT_PHASE(0.000),
|
|
.CLKIN1_PERIOD(5.000),
|
|
.CLKIN2_PERIOD(0.000),
|
|
.CLKOUT0_DIVIDE_F(12.500),
|
|
.CLKOUT0_PHASE(0.000),
|
|
.CLKOUT0_DUTY_CYCLE(0.500),
|
|
.CLKOUT1_DIVIDE(20),
|
|
.CLKOUT1_PHASE(0.000),
|
|
.CLKOUT1_DUTY_CYCLE(0.500),
|
|
.CLKOUT2_DIVIDE(8),
|
|
.CLKOUT2_PHASE(0.000),
|
|
.CLKOUT2_DUTY_CYCLE(0.500),
|
|
.DIVCLK_DIVIDE(1),
|
|
.REF_JITTER1(0.010),
|
|
.REF_JITTER2(0.010),
|
|
.STARTUP_WAIT("FALSE")
|
|
) u_clock_mmcm (
|
|
.CLKIN1(sysclk_200),
|
|
.CLKIN2(1'b0),
|
|
.CLKINSEL(1'b1),
|
|
.CLKFBIN(fabric_clkfb_buf),
|
|
.CLKFBOUT(fabric_clkfb),
|
|
.CLKFBOUTB(),
|
|
.CLKOUT0(),
|
|
.CLKOUT0B(),
|
|
.CLKOUT1(pll_fabric_clk),
|
|
.CLKOUT1B(),
|
|
.CLKOUT2(),
|
|
.CLKOUT2B(),
|
|
.CLKOUT3(),
|
|
.CLKOUT3B(),
|
|
.CLKOUT4(),
|
|
.CLKOUT5(),
|
|
.CLKOUT6(),
|
|
.DADDR(7'd0),
|
|
.DCLK(1'b0),
|
|
.DEN(1'b0),
|
|
.DI(16'd0),
|
|
.DWE(1'b0),
|
|
.DO(),
|
|
.DRDY(),
|
|
.LOCKED(fabric_pll_locked),
|
|
.PSCLK(1'b0),
|
|
.PSEN(1'b0),
|
|
.PSINCDEC(1'b0),
|
|
.PSDONE(),
|
|
.PWRDWN(1'b0),
|
|
.RST(board_reset)
|
|
);
|
|
|
|
BUFG u_pll_feedback_buf (
|
|
.I(fabric_clkfb),
|
|
.O(fabric_clkfb_buf)
|
|
);
|
|
|
|
BUFG u_fabric_clk_buf (
|
|
.I(pll_fabric_clk),
|
|
.O(fabric_clk)
|
|
);
|
|
|
|
wire rf_clk_pmod_ibuf;
|
|
|
|
// PMOD mode feeds the GPS RF domain directly from the external sampler.
|
|
IBUF u_rf_clk_pmod_ibuf (
|
|
.I(rf_clk_pmod),
|
|
.O(rf_clk_pmod_ibuf)
|
|
);
|
|
|
|
BUFG u_rf_clk_pmod_buf (
|
|
.I(rf_clk_pmod_ibuf),
|
|
.O(gps_rf_clk_selected)
|
|
);
|
|
|
|
assign gps_rf_data_selected = rf_data_pmod;
|
|
assign gps_rf_ready = 1'b1;
|
|
|
|
|
|
// GPS processing clocks are synthesized from the RF sample clock, not the
|
|
// board crystal. Two MMCM stages keep 80/125 MHz within 0.01 ppm of nominal
|
|
// for the 16.367981 MHz sampler while leaving the Rocket fabric independent.
|
|
MMCME2_ADV #(
|
|
.BANDWIDTH("OPTIMIZED"),
|
|
.CLKFBOUT_MULT_F(58.125),
|
|
.CLKFBOUT_PHASE(0.000),
|
|
.CLKIN1_PERIOD(61.095),
|
|
.CLKIN2_PERIOD(0.000),
|
|
.CLKOUT0_DIVIDE_F(17.125),
|
|
.CLKOUT0_PHASE(0.000),
|
|
.CLKOUT0_DUTY_CYCLE(0.500),
|
|
.DIVCLK_DIVIDE(1),
|
|
.REF_JITTER1(0.010),
|
|
.REF_JITTER2(0.010),
|
|
.STARTUP_WAIT("FALSE")
|
|
) u_gps_ref_mmcm (
|
|
.CLKIN1(gps_rf_clk_selected),
|
|
.CLKIN2(1'b0),
|
|
.CLKINSEL(1'b1),
|
|
.CLKFBIN(gps_ref_clkfb_buf),
|
|
.CLKFBOUT(gps_ref_clkfb),
|
|
.CLKFBOUTB(),
|
|
.CLKOUT0(pll_gps_ref_clk),
|
|
.CLKOUT0B(),
|
|
.CLKOUT1(),
|
|
.CLKOUT1B(),
|
|
.CLKOUT2(),
|
|
.CLKOUT2B(),
|
|
.CLKOUT3(),
|
|
.CLKOUT3B(),
|
|
.CLKOUT4(),
|
|
.CLKOUT5(),
|
|
.CLKOUT6(),
|
|
.DADDR(7'd0),
|
|
.DCLK(1'b0),
|
|
.DEN(1'b0),
|
|
.DI(16'd0),
|
|
.DWE(1'b0),
|
|
.DO(),
|
|
.DRDY(),
|
|
.LOCKED(gps_ref_pll_locked),
|
|
.PSCLK(1'b0),
|
|
.PSEN(1'b0),
|
|
.PSINCDEC(1'b0),
|
|
.PSDONE(),
|
|
.PWRDWN(1'b0),
|
|
.RST(board_reset)
|
|
);
|
|
|
|
BUFG u_gps_ref_feedback_buf (
|
|
.I(gps_ref_clkfb),
|
|
.O(gps_ref_clkfb_buf)
|
|
);
|
|
|
|
BUFG u_gps_ref_clk_buf (
|
|
.I(pll_gps_ref_clk),
|
|
.O(gps_ref_clk_gen)
|
|
);
|
|
|
|
MMCME2_ADV #(
|
|
.BANDWIDTH("OPTIMIZED"),
|
|
.CLKFBOUT_MULT_F(18.000),
|
|
.CLKFBOUT_PHASE(0.000),
|
|
.CLKIN1_PERIOD(18.000),
|
|
.CLKIN2_PERIOD(0.000),
|
|
.CLKOUT0_DIVIDE_F(12.500),
|
|
.CLKOUT0_PHASE(0.000),
|
|
.CLKOUT0_DUTY_CYCLE(0.500),
|
|
.CLKOUT1_DIVIDE(8),
|
|
.CLKOUT1_PHASE(0.000),
|
|
.CLKOUT1_DUTY_CYCLE(0.500),
|
|
.DIVCLK_DIVIDE(1),
|
|
.REF_JITTER1(0.010),
|
|
.REF_JITTER2(0.010),
|
|
.STARTUP_WAIT("FALSE")
|
|
) u_gps_domain_mmcm (
|
|
.CLKIN1(gps_ref_clk_gen),
|
|
.CLKIN2(1'b0),
|
|
.CLKINSEL(1'b1),
|
|
.CLKFBIN(gps_clkfb_buf),
|
|
.CLKFBOUT(gps_clkfb),
|
|
.CLKFBOUTB(),
|
|
.CLKOUT0(pll_gps_acq_clk),
|
|
.CLKOUT0B(),
|
|
.CLKOUT1(pll_gps_trck_clk),
|
|
.CLKOUT1B(),
|
|
.CLKOUT2(),
|
|
.CLKOUT2B(),
|
|
.CLKOUT3(),
|
|
.CLKOUT3B(),
|
|
.CLKOUT4(),
|
|
.CLKOUT5(),
|
|
.CLKOUT6(),
|
|
.DADDR(7'd0),
|
|
.DCLK(1'b0),
|
|
.DEN(1'b0),
|
|
.DI(16'd0),
|
|
.DWE(1'b0),
|
|
.DO(),
|
|
.DRDY(),
|
|
.LOCKED(gps_domain_pll_locked),
|
|
.PSCLK(1'b0),
|
|
.PSEN(1'b0),
|
|
.PSINCDEC(1'b0),
|
|
.PSDONE(),
|
|
.PWRDWN(1'b0),
|
|
.RST(board_reset | ~gps_ref_pll_locked)
|
|
);
|
|
|
|
BUFG u_gps_domain_feedback_buf (
|
|
.I(gps_clkfb),
|
|
.O(gps_clkfb_buf)
|
|
);
|
|
|
|
BUFG u_gps_acq_clk_buf (
|
|
.I(pll_gps_acq_clk),
|
|
.O(gps_acq_clk_gen)
|
|
);
|
|
|
|
BUFG u_gps_trck_clk_buf (
|
|
.I(pll_gps_trck_clk),
|
|
.O(gps_trck_clk_gen)
|
|
);
|
|
|
|
wire pll_ready_async = fabric_pll_locked & gps_clock_locked & gps_rf_ready & cpu_resetn;
|
|
(* async_reg = "true" *) reg [2:0] pll_ready_sync = 3'b000;
|
|
reg [15:0] reset_shift = 16'hFFFF;
|
|
always @(posedge fabric_clk) begin
|
|
pll_ready_sync <= {pll_ready_sync[1:0], pll_ready_async};
|
|
if (!pll_ready_sync[2]) begin
|
|
reset_shift <= 16'hFFFF;
|
|
end else begin
|
|
reset_shift <= {reset_shift[14:0], 1'b0};
|
|
end
|
|
end
|
|
|
|
wire fabric_reset = reset_shift[15];
|
|
reg [31:0] heartbeat;
|
|
always @(posedge fabric_clk) begin
|
|
if (fabric_reset) begin
|
|
heartbeat <= 32'd0;
|
|
end else begin
|
|
heartbeat <= heartbeat + 32'd1;
|
|
end
|
|
end
|
|
|
|
|
|
|
|
wire io_aggregator_3_clock;
|
|
wire io_aggregator_3_reset;
|
|
wire io_aggregator_2_clock;
|
|
wire io_aggregator_2_reset;
|
|
wire io_aggregator_1_clock;
|
|
wire io_aggregator_1_reset;
|
|
wire io_aggregator_0_clock;
|
|
wire io_aggregator_0_reset;
|
|
wire resetctrl_hartIsInReset_0;
|
|
wire debug_clock;
|
|
wire debug_reset;
|
|
wire debug_clockeddmi_dmi_req_ready;
|
|
wire debug_clockeddmi_dmi_req_valid;
|
|
wire [6:0] debug_clockeddmi_dmi_req_bits_addr;
|
|
wire [31:0] debug_clockeddmi_dmi_req_bits_data;
|
|
wire [1:0] debug_clockeddmi_dmi_req_bits_op;
|
|
wire debug_clockeddmi_dmi_resp_ready;
|
|
wire debug_clockeddmi_dmi_resp_valid;
|
|
wire [31:0] debug_clockeddmi_dmi_resp_bits_data;
|
|
wire [1:0] debug_clockeddmi_dmi_resp_bits_resp;
|
|
wire debug_clockeddmi_dmiClock;
|
|
wire debug_clockeddmi_dmiReset;
|
|
wire debug_ndreset;
|
|
wire debug_dmactive;
|
|
wire debug_dmactiveAck;
|
|
wire uart_rxd;
|
|
wire uart_txd;
|
|
wire spi_sck;
|
|
wire spi_csn;
|
|
wire [3:0] spi_dq_i;
|
|
wire [3:0] spi_dq_o;
|
|
wire [3:0] spi_dq_oe;
|
|
wire [3:0] pmod_spi_dq_i;
|
|
wire [3:0] pmod_spi_dq_o;
|
|
wire [3:0] pmod_spi_dq_oe;
|
|
wire gps_acq_clk;
|
|
wire gps_trck_clk;
|
|
wire gps_rf_clk;
|
|
wire [3:0] gps_rf_data;
|
|
|
|
wire soc_reset = fabric_reset | debug_ndreset;
|
|
|
|
wire bscan_capture;
|
|
wire bscan_drck;
|
|
wire bscan_reset;
|
|
wire bscan_runtest;
|
|
wire bscan_sel;
|
|
wire bscan_shift;
|
|
wire bscan_tck;
|
|
wire bscan_tdi;
|
|
wire bscan_tms;
|
|
wire bscan_tdo;
|
|
wire bscan_update;
|
|
|
|
BSCANE2 #(
|
|
.DISABLE_JTAG("FALSE"),
|
|
.JTAG_CHAIN(4)
|
|
) u_rocket_bscan (
|
|
.CAPTURE(bscan_capture),
|
|
.DRCK(bscan_drck),
|
|
.RESET(bscan_reset),
|
|
.RUNTEST(bscan_runtest),
|
|
.SEL(bscan_sel),
|
|
.SHIFT(bscan_shift),
|
|
.TCK(bscan_tck),
|
|
.TDI(bscan_tdi),
|
|
.TMS(bscan_tms),
|
|
.UPDATE(bscan_update),
|
|
.TDO(bscan_tdo)
|
|
);
|
|
|
|
rocket_bscan_dmi_tunnel u_rocket_bscan_dmi_tunnel (
|
|
.tck(bscan_tck),
|
|
.reset(fabric_reset | bscan_reset),
|
|
.bscan_capture(bscan_capture),
|
|
.bscan_sel(bscan_sel),
|
|
.bscan_shift(bscan_shift),
|
|
.bscan_tdi(bscan_tdi),
|
|
.bscan_update(bscan_update),
|
|
.bscan_tdo(bscan_tdo),
|
|
.dmi_clock(debug_clockeddmi_dmiClock),
|
|
.dmi_reset(debug_clockeddmi_dmiReset),
|
|
.dmi_req_ready(debug_clockeddmi_dmi_req_ready),
|
|
.dmi_req_valid(debug_clockeddmi_dmi_req_valid),
|
|
.dmi_req_addr(debug_clockeddmi_dmi_req_bits_addr),
|
|
.dmi_req_data(debug_clockeddmi_dmi_req_bits_data),
|
|
.dmi_req_op(debug_clockeddmi_dmi_req_bits_op),
|
|
.dmi_resp_ready(debug_clockeddmi_dmi_resp_ready),
|
|
.dmi_resp_valid(debug_clockeddmi_dmi_resp_valid),
|
|
.dmi_resp_data(debug_clockeddmi_dmi_resp_bits_data),
|
|
.dmi_resp_resp(debug_clockeddmi_dmi_resp_bits_resp)
|
|
);
|
|
|
|
assign spi_dq_i = qspi_d;
|
|
assign qspi_d[0] = spi_dq_oe[0] ? spi_dq_o[0] : 1'bz;
|
|
assign qspi_d[1] = spi_dq_oe[1] ? spi_dq_o[1] : 1'bz;
|
|
assign qspi_d[2] = spi_dq_oe[2] ? spi_dq_o[2] : 1'bz;
|
|
assign qspi_d[3] = spi_dq_oe[3] ? spi_dq_o[3] : 1'bz;
|
|
assign qspi_csn = spi_csn;
|
|
|
|
STARTUPE2 #(
|
|
.PROG_USR("FALSE"),
|
|
.SIM_CCLK_FREQ(0.0)
|
|
) u_cfg_flash_startup (
|
|
.CFGCLK(),
|
|
.CFGMCLK(),
|
|
.EOS(),
|
|
.PREQ(),
|
|
.CLK(1'b0),
|
|
.GSR(1'b0),
|
|
.GTS(1'b0),
|
|
.KEYCLEARB(1'b1),
|
|
.PACK(1'b0),
|
|
.USRCCLKO(spi_sck),
|
|
.USRCCLKTS(1'b0),
|
|
.USRDONEO(1'b1),
|
|
.USRDONETS(1'b1)
|
|
);
|
|
|
|
assign pmod_spi_dq_i = pmod_spi_dq;
|
|
assign pmod_spi_dq[0] = pmod_spi_dq_oe[0] ? pmod_spi_dq_o[0] : 1'bz;
|
|
assign pmod_spi_dq[1] = pmod_spi_dq_oe[1] ? pmod_spi_dq_o[1] : 1'bz;
|
|
assign pmod_spi_dq[2] = pmod_spi_dq_oe[2] ? pmod_spi_dq_o[2] : 1'bz;
|
|
assign pmod_spi_dq[3] = pmod_spi_dq_oe[3] ? pmod_spi_dq_o[3] : 1'bz;
|
|
|
|
assign io_aggregator_3_clock = fabric_clk;
|
|
assign io_aggregator_3_reset = soc_reset;
|
|
assign io_aggregator_2_clock = fabric_clk;
|
|
assign io_aggregator_2_reset = soc_reset;
|
|
assign io_aggregator_1_clock = fabric_clk;
|
|
assign io_aggregator_1_reset = soc_reset;
|
|
assign io_aggregator_0_clock = fabric_clk;
|
|
assign io_aggregator_0_reset = soc_reset;
|
|
assign resetctrl_hartIsInReset_0 = soc_reset;
|
|
assign debug_clock = fabric_clk;
|
|
assign debug_reset = fabric_reset;
|
|
assign debug_dmactiveAck = debug_dmactive;
|
|
assign uart_rxd = uart_tx_in;
|
|
assign gps_acq_clk = gps_acq_clk_gen;
|
|
assign gps_trck_clk = gps_trck_clk_gen;
|
|
assign gps_rf_clk = gps_rf_clk_selected;
|
|
assign gps_rf_data = gps_rf_data_selected;
|
|
|
|
assign led = {
|
|
heartbeat[25], heartbeat[24], ~cpu_resetn, fabric_reset,
|
|
debug_clockeddmi_dmi_req_ready,
|
|
debug_dmactive,
|
|
debug_ndreset,
|
|
uart_txd
|
|
};
|
|
assign uart_rx_out = uart_txd;
|
|
|
|
|
|
|
|
|
|
|
|
(* dont_touch = "true", keep_hierarchy = "yes" *)
|
|
VCU118RocketSystem u_rocket (
|
|
.io_aggregator_3_clock(io_aggregator_3_clock),
|
|
.io_aggregator_3_reset(io_aggregator_3_reset),
|
|
.io_aggregator_2_clock(io_aggregator_2_clock),
|
|
.io_aggregator_2_reset(io_aggregator_2_reset),
|
|
.io_aggregator_1_clock(io_aggregator_1_clock),
|
|
.io_aggregator_1_reset(io_aggregator_1_reset),
|
|
.io_aggregator_0_clock(io_aggregator_0_clock),
|
|
.io_aggregator_0_reset(io_aggregator_0_reset),
|
|
.resetctrl_hartIsInReset_0(resetctrl_hartIsInReset_0),
|
|
.debug_clock(debug_clock),
|
|
.debug_reset(debug_reset),
|
|
.debug_clockeddmi_dmi_req_ready(debug_clockeddmi_dmi_req_ready),
|
|
.debug_clockeddmi_dmi_req_valid(debug_clockeddmi_dmi_req_valid),
|
|
.debug_clockeddmi_dmi_req_bits_addr(debug_clockeddmi_dmi_req_bits_addr),
|
|
.debug_clockeddmi_dmi_req_bits_data(debug_clockeddmi_dmi_req_bits_data),
|
|
.debug_clockeddmi_dmi_req_bits_op(debug_clockeddmi_dmi_req_bits_op),
|
|
.debug_clockeddmi_dmi_resp_ready(debug_clockeddmi_dmi_resp_ready),
|
|
.debug_clockeddmi_dmi_resp_valid(debug_clockeddmi_dmi_resp_valid),
|
|
.debug_clockeddmi_dmi_resp_bits_data(debug_clockeddmi_dmi_resp_bits_data),
|
|
.debug_clockeddmi_dmi_resp_bits_resp(debug_clockeddmi_dmi_resp_bits_resp),
|
|
.debug_clockeddmi_dmiClock(debug_clockeddmi_dmiClock),
|
|
.debug_clockeddmi_dmiReset(debug_clockeddmi_dmiReset),
|
|
.debug_ndreset(debug_ndreset),
|
|
.debug_dmactive(debug_dmactive),
|
|
.debug_dmactiveAck(debug_dmactiveAck),
|
|
.uart_rxd(uart_rxd),
|
|
.uart_txd(uart_txd),
|
|
.spi_sck(spi_sck),
|
|
.spi_csn(spi_csn),
|
|
.spi_dq_i(spi_dq_i),
|
|
.spi_dq_o(spi_dq_o),
|
|
.spi_dq_oe(spi_dq_oe),
|
|
.pmod_spi_sck(pmod_spi_sck),
|
|
.pmod_spi_csn(pmod_spi_csn),
|
|
.pmod_spi_dq_i(pmod_spi_dq_i),
|
|
.pmod_spi_dq_o(pmod_spi_dq_o),
|
|
.pmod_spi_dq_oe(pmod_spi_dq_oe),
|
|
.pmod_irq(pmod_irq),
|
|
.gps_acq_clk(gps_acq_clk),
|
|
.gps_trck_clk(gps_trck_clk),
|
|
.gps_rf_clk(gps_rf_clk),
|
|
.gps_rf_data(gps_rf_data),
|
|
.gps_pps(gps_pps)
|
|
);
|
|
endmodule
|