Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

target/fpga: Add Hyperram #127

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dependencies:
riscv-dbg: { git: "https://github.com/pulp-platform/riscv-dbg.git", version: 0.8.1 }
serial_link: { git: "https://github.com/pulp-platform/serial_link.git", version: 1.1.1 }
unbent: { git: "https://github.com/pulp-platform/unbent.git", version: 0.1.6 }
hyperbus: { git: "https://github.com/pulp-platform/hyperbus.git", rev: bd5688dd1d3ed24e0a6bf2296009d525230c93a0 }

export_include_dirs:
- hw/include
Expand Down
2 changes: 1 addition & 1 deletion hw/cheshire_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ package cheshire_pkg;
LlcAmoPostCut : 1,
LlcOutConnect : 1,
LlcOutRegionStart : 'h8000_0000,
LlcOutRegionEnd : 'h1_0000_0000,
LlcOutRegionEnd : 'h8200_0000,
// VGA: RGB332
VgaRedWidth : 3,
VgaGreenWidth : 3,
Expand Down
91 changes: 91 additions & 0 deletions target/xilinx/constraints/genesys2.xdc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,97 @@ create_clock -period $SYS_TCK -name sys_clk [get_ports sys_clk_p]
set SOC_TCK 20.0
set soc_clk [get_clocks -of_objects [get_pins i_clkwiz/clk_50]]

############
# Hyperram #
############

set period_hyperbus 40

## Create RWDS clock (10MHz)
create_clock -period [expr $period_hyperbus] -name rwds0_clk [get_ports FMC_hyper0_rwds]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets iobuf_rwds0_i/O]

create_clock -period [expr $period_hyperbus] -name rwds1_clk [get_ports FMC_hyper1_rwds]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets iobuf_rwds1_i/O]

## Create the PHY clock
create_generated_clock [get_pins i_hyperbus/clock_generator.ddr_clk/clk0_o] -name clk_phy -source [get_pins i_clkwiz/clk_50] -divide_by 2
create_generated_clock [get_pins i_hyperbus/clock_generator.ddr_clk/clk90_o] -name clk_phy_90 -source [get_pins i_clkwiz/clk_50] -edges {2 4 6}

## PHY0
set clk_rx_shift [expr $period_hyperbus/10]
set rwds_input_delay [expr $period_hyperbus/4]

create_generated_clock [get_pins i_hyperbus/i_phy/phy_wrap.phy_unroll[0].i_phy/i_trx/i_delay_rx_rwds_90/in_i] \
-name clk_rwds_0 -edges {1 2 3} -edge_shift "$clk_rx_shift $clk_rx_shift $clk_rx_shift" \
-source [get_ports FMC_hyper0_rwds]

create_generated_clock [get_nets i_hyperbus/i_phy/phy_wrap.phy_unroll[0].i_phy/i_trx/i_rx_rwds_cdc_fifo/src_clk_i] \
-name clk_rwds_sample0 -invert -divide_by 1 \
-source [get_pins i_hyperbus/i_phy/phy_wrap.phy_unroll[0].i_phy/i_trx/i_delay_rx_rwds_90/in_i]

## PHY1
create_generated_clock [get_pins i_hyperbus/i_phy/phy_wrap.phy_unroll[1].i_phy/i_trx/i_delay_rx_rwds_90/in_i] \
-name clk_rwds_1 -edges {1 2 3} -edge_shift "$clk_rx_shift $clk_rx_shift $clk_rx_shift" \
-source [get_ports FMC_hyper1_rwds]

create_generated_clock [get_nets i_hyperbus/i_phy/phy_wrap.phy_unroll[1].i_phy/i_trx/i_rx_rwds_cdc_fifo/src_clk_i] \
-name clk_rwds_sample1 -invert -divide_by 1 \
-source [get_pins i_hyperbus/i_phy/phy_wrap.phy_unroll[1].i_phy/i_trx/i_delay_rx_rwds_90/in_i]

## I/O constraints
set output_ports {{FMC_hyper*_dq*} FMC_hyper*_rwds}
set_output_delay [expr $period_hyperbus/2 ] -clock clk_phy_90 [get_ports $output_ports] -max
set_output_delay [expr $period_hyperbus/-2] -clock clk_phy_90 [get_ports $output_ports] -min -add_delay
set_output_delay [expr $period_hyperbus/2 ] -clock clk_phy_90 [get_ports $output_ports] -max -clock_fall -add_delay
set_output_delay [expr $period_hyperbus/-2] -clock clk_phy_90 [get_ports $output_ports] -min -clock_fall -add_delay

set input_ports {{FMC_hyper*_dq*} FMC_hyper*_rwds}
set_input_delay -max [expr $period_hyperbus/2] -clock clk_phy [get_ports $input_ports]
set_input_delay -min [expr $period_hyperbus/2] -clock clk_phy [get_ports $input_ports] -add_delay
set_input_delay -max [expr $period_hyperbus/2] -clock clk_phy [get_ports $input_ports] -add_delay -clock_fall
set_input_delay -min [expr $period_hyperbus/2] -clock clk_phy [get_ports $input_ports] -add_delay -clock_fall

## Async
set_clock_groups -asynchronous -group [get_clocks sys_clk] \
-group [get_clocks clk_phy] \
-group [get_clocks clk_phy_90] \
-group [get_clocks { rwds0_clk clk_rwds_0 clk_rwds_sample0 }] \
-group [get_clocks { rwds1_clk clk_rwds_1 clk_rwds_sample1 }]

## FMC
# Hyper 0
set_property -dict { PACKAGE_PIN D27 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_ck]
set_property -dict { PACKAGE_PIN C27 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_ckn]
set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_csn0]
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_csn1]
set_property -dict { PACKAGE_PIN F26 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_rwds]
set_property -dict { PACKAGE_PIN D22 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_reset]
set_property -dict { PACKAGE_PIN B29 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_dqio0]
set_property -dict { PACKAGE_PIN C29 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_dqio1]
set_property -dict { PACKAGE_PIN E30 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_dqio2]
set_property -dict { PACKAGE_PIN E29 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_dqio3]
set_property -dict { PACKAGE_PIN E23 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_dqio4]
set_property -dict { PACKAGE_PIN D23 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_dqio5]
set_property -dict { PACKAGE_PIN G22 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_dqio6]
set_property -dict { PACKAGE_PIN F22 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper0_dqio7]

# Hyper 1
set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_ck]
set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_ckn]
set_property -dict { PACKAGE_PIN F17 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_csn0]
set_property -dict { PACKAGE_PIN E21 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_csn1]
set_property -dict { PACKAGE_PIN A20 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_rwds]
set_property -dict { PACKAGE_PIN B24 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_reset]
set_property -dict { PACKAGE_PIN B30 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_dqio0]
set_property -dict { PACKAGE_PIN A30 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_dqio1]
set_property -dict { PACKAGE_PIN B28 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_dqio2]
set_property -dict { PACKAGE_PIN A28 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_dqio3]
set_property -dict { PACKAGE_PIN D29 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_dqio4]
set_property -dict { PACKAGE_PIN C30 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_dqio5]
set_property -dict { PACKAGE_PIN B27 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_dqio6]
set_property -dict { PACKAGE_PIN A27 IOSTANDARD LVCMOS12 } [get_ports FMC_hyper1_dqio7]

############
# Switches #
############
Expand Down
124 changes: 122 additions & 2 deletions target/xilinx/src/cheshire_top_xilinx.sv
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ module cheshire_top_xilinx (
`ifdef USE_DDR3
`DDR3_INTF
`endif
`ifdef USE_HYPERBUS
`HYPERBUS_INTF
`endif

output logic uart_tx_o,
input logic uart_rx_i
Expand All @@ -97,6 +100,14 @@ module cheshire_top_xilinx (
ret.VgaRedWidth = 5;
ret.VgaGreenWidth = 6;
ret.VgaBlueWidth = 5;
ret.LlcNotBypass = 0;
ret.Dma = 0;
ret.Vga = 0;
ret.RegExtNumSlv = 1;
ret.RegExtNumRules = 1;
ret.RegExtRegionIdx [0] = 0;
ret.RegExtRegionStart [0] = 'h4000_0000;
ret.RegExtRegionEnd [0] = 'h4010_0000;
return ret;
endfunction

Expand Down Expand Up @@ -390,6 +401,115 @@ module cheshire_top_xilinx (
);
`endif


//////////////
// Hyperbus //
//////////////

reg_req_t reg_ext_slv_req;
reg_rsp_t reg_ext_slv_rsp;

`ifdef USE_HYPERBUS
// Signals
logic [1:0] hyper_reset_no;
logic [1:0][1:0] hyper_cs_no;
logic [1:0] hyper_ck_o;
logic [1:0] hyper_ck_no;
logic [1:0] hyper_rwds_o;
logic [1:0] hyper_rwds_i;
logic [1:0] hyper_rwds_oe_o;
logic [1:0][7:0] hyper_dq_o;
logic [1:0][7:0] hyper_dq_i;
logic [1:0] hyper_dq_oe_o;

// Hyperbus address rules
typedef struct packed {
int unsigned idx;
logic [FPGACfg.AddrWidth-1:0] start_addr;
logic [FPGACfg.AddrWidth-1:0] end_addr;
} hyper_addr_rule_t;

// Hyperbus
hyperbus #(
.NumChips ( 2 ),
.NumPhys ( 2 ),
.IsClockODelayed ( 0 ),
.AxiAddrWidth ( FPGACfg.AddrWidth ),
.AxiDataWidth ( FPGACfg.AxiDataWidth ),
.AxiIdWidth ( $bits(axi_llc_id_t) ),
.AxiUserWidth ( FPGACfg.AxiUserWidth ),
.axi_req_t ( axi_llc_req_t ),
.axi_rsp_t ( axi_llc_rsp_t ),
.axi_w_chan_t ( axi_llc_w_chan_t ),
.axi_b_chan_t ( axi_llc_b_chan_t ),
.axi_ar_chan_t ( axi_llc_ar_chan_t ),
.axi_r_chan_t ( axi_llc_r_chan_t ),
.axi_aw_chan_t ( axi_llc_aw_chan_t ),
.RegAddrWidth ( FPGACfg.AddrWidth ),
.RegDataWidth ( 32 ),
.reg_req_t ( reg_req_t ),
.reg_rsp_t ( reg_rsp_t ),
.axi_rule_t ( hyper_addr_rule_t ),
.RstChipBase ( 32'(FPGACfg.LlcOutRegionStart) ),
.RstChipSpace ( 32'(8*1024) )
) i_hyperbus (
// WARNING: Keeping system and PHY synchronous works only with careful constraints.
// DO NOT copy-paste this to other projects without consideration; you were warned.
.clk_phy_i ( soc_clk ),
.rst_phy_ni ( rst_n ),
.clk_sys_i ( soc_clk ),
.rst_sys_ni ( rst_n ),
.test_mode_i,
.axi_req_i ( axi_llc_mst_req ),
.axi_rsp_o ( axi_llc_mst_rsp ),
.reg_req_i ( reg_ext_slv_req ),
.reg_rsp_o ( reg_ext_slv_rsp ),
.hyper_cs_no,
.hyper_ck_o,
.hyper_ck_no,
.hyper_rwds_o,
.hyper_rwds_i,
.hyper_rwds_oe_o,
.hyper_dq_i,
.hyper_dq_o,
.hyper_dq_oe_o,
.hyper_reset_no
);

// Pads
// PHY0
(* PULLDOWN = "YES" *) IOBUF iobuf_csn00_i ( .T(1'b0), .I(hyper_cs_no[0][0]), .O(), .IO(FMC_hyper0_csn0) );
(* PULLDOWN = "YES" *) IOBUF iobuf_csn01_i ( .T(1'b0), .I(hyper_cs_no[0][1]), .O(), .IO(FMC_hyper0_csn1) );
(* PULLDOWN = "YES" *) IOBUF iobuf_ck0_i ( .T(1'b0), .I(hyper_ck_o[0]), .O(), .IO(FMC_hyper0_ck) );
(* PULLDOWN = "YES" *) IOBUF iobuf_ckn0_i ( .T(1'b0), .I(hyper_ck_no[0]), .O(), .IO(FMC_hyper0_ckn) );
(* PULLDOWN = "YES" *) IOBUF iobuf_rwds0_i ( .T(~hyper_rwds_oe_o[0]), .I(hyper_rwds_o[0]), .O(hyper_rwds_i[0]), .IO(FMC_hyper0_rwds) );
(* PULLDOWN = "YES" *) IOBUF iobuf_rst0_i ( .T(1'b0), .I(hyper_reset_no[0]), .O(), .IO(FMC_hyper0_reset) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq00_i ( .T(~hyper_dq_oe_o[0]), .I(hyper_dq_o[0][0]), .O(hyper_dq_i[0][0]), .IO(FMC_hyper0_dqio0) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq01_i ( .T(~hyper_dq_oe_o[0]), .I(hyper_dq_o[0][1]), .O(hyper_dq_i[0][1]), .IO(FMC_hyper0_dqio1) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq02_i ( .T(~hyper_dq_oe_o[0]), .I(hyper_dq_o[0][2]), .O(hyper_dq_i[0][2]), .IO(FMC_hyper0_dqio2) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq03_i ( .T(~hyper_dq_oe_o[0]), .I(hyper_dq_o[0][3]), .O(hyper_dq_i[0][3]), .IO(FMC_hyper0_dqio3) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq04_i ( .T(~hyper_dq_oe_o[0]), .I(hyper_dq_o[0][4]), .O(hyper_dq_i[0][4]), .IO(FMC_hyper0_dqio4) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq05_i ( .T(~hyper_dq_oe_o[0]), .I(hyper_dq_o[0][5]), .O(hyper_dq_i[0][5]), .IO(FMC_hyper0_dqio5) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq06_i ( .T(~hyper_dq_oe_o[0]), .I(hyper_dq_o[0][6]), .O(hyper_dq_i[0][6]), .IO(FMC_hyper0_dqio6) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq07_i ( .T(~hyper_dq_oe_o[0]), .I(hyper_dq_o[0][7]), .O(hyper_dq_i[0][7]), .IO(FMC_hyper0_dqio7) );

// PHY1
(* PULLDOWN = "YES" *) IOBUF iobuf_csn10_i ( .T(1'b0), .I(hyper_cs_no[1][0]), .O(), .IO(FMC_hyper1_csn0) );
(* PULLDOWN = "YES" *) IOBUF iobuf_csn11_i ( .T(1'b0), .I(hyper_cs_no[1][1]), .O(), .IO(FMC_hyper1_csn1) );
(* PULLDOWN = "YES" *) IOBUF iobuf_ck1_i ( .T(1'b0), .I(hyper_ck_o[1]), .O(), .IO(FMC_hyper1_ck) );
(* PULLDOWN = "YES" *) IOBUF iobuf_ckn1_i ( .T(1'b0), .I(hyper_ck_no[1]), .O(), .IO(FMC_hyper1_ckn) );
(* PULLDOWN = "YES" *) IOBUF iobuf_rwds1_i ( .T(~hyper_rwds_oe_o[1]), .I(hyper_rwds_o[1]), .O(hyper_rwds_i[1]), .IO(FMC_hyper1_rwds) );
(* PULLDOWN = "YES" *) IOBUF iobuf_rst1_i ( .T(1'b0), .I(hyper_reset_no[1]), .O(), .IO(FMC_hyper1_reset) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq10_i ( .T(~hyper_dq_oe_o[1]), .I(hyper_dq_o[1][0]), .O(hyper_dq_i[1][0]), .IO(FMC_hyper1_dqio0) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq11_i ( .T(~hyper_dq_oe_o[1]), .I(hyper_dq_o[1][1]), .O(hyper_dq_i[1][1]), .IO(FMC_hyper1_dqio1) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq12_i ( .T(~hyper_dq_oe_o[1]), .I(hyper_dq_o[1][2]), .O(hyper_dq_i[1][2]), .IO(FMC_hyper1_dqio2) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq13_i ( .T(~hyper_dq_oe_o[1]), .I(hyper_dq_o[1][3]), .O(hyper_dq_i[1][3]), .IO(FMC_hyper1_dqio3) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq14_i ( .T(~hyper_dq_oe_o[1]), .I(hyper_dq_o[1][4]), .O(hyper_dq_i[1][4]), .IO(FMC_hyper1_dqio4) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq15_i ( .T(~hyper_dq_oe_o[1]), .I(hyper_dq_o[1][5]), .O(hyper_dq_i[1][5]), .IO(FMC_hyper1_dqio5) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq16_i ( .T(~hyper_dq_oe_o[1]), .I(hyper_dq_o[1][6]), .O(hyper_dq_i[1][6]), .IO(FMC_hyper1_dqio6) );
(* PULLDOWN = "YES" *) IOBUF iobuf_dq17_i ( .T(~hyper_dq_oe_o[1]), .I(hyper_dq_o[1][7]), .O(hyper_dq_i[1][7]), .IO(FMC_hyper1_dqio7) );
`endif

//////////////////
// Cheshire SoC //
//////////////////
Expand Down Expand Up @@ -417,8 +537,8 @@ module cheshire_top_xilinx (
.axi_ext_mst_rsp_o ( ),
.axi_ext_slv_req_o ( ),
.axi_ext_slv_rsp_i ( '0 ),
.reg_ext_slv_req_o ( ),
.reg_ext_slv_rsp_i ( '0 ),
.reg_ext_slv_req_o ( reg_ext_slv_req ),
.reg_ext_slv_rsp_i ( reg_ext_slv_rsp ),
.intr_ext_i ( '0 ),
.intr_ext_o ( ),
.xeip_ext_o ( ),
Expand Down
35 changes: 34 additions & 1 deletion target/xilinx/src/phy_definitions.svh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
`define USE_JTAG_TRSTN
`define USE_SD
`define USE_SWITCHES
`define USE_DDR3
`define USE_HYPERRAM
`define USE_FAN
`define USE_VIO
`define USE_I2C
Expand All @@ -38,6 +38,9 @@
// DRAM INTERFACES //
/////////////////////

`ifdef USE_HYPERRAM
`define USE_HYPERBUS
`endif
`ifdef USE_DDR4
`define USE_DDR
`endif
Expand Down Expand Up @@ -78,6 +81,36 @@
output [3:0] ddr3_dm, \
output [0:0] ddr3_odt,

`define HYPERBUS_INTF \
inout FMC_hyper0_dqio0, \
inout FMC_hyper0_dqio1, \
inout FMC_hyper0_dqio2, \
inout FMC_hyper0_dqio3, \
inout FMC_hyper0_dqio4, \
inout FMC_hyper0_dqio5, \
inout FMC_hyper0_dqio6, \
inout FMC_hyper0_dqio7, \
inout FMC_hyper0_ck, \
inout FMC_hyper0_ckn, \
inout FMC_hyper0_csn0, \
inout FMC_hyper0_csn1, \
inout FMC_hyper0_rwds, \
inout FMC_hyper0_reset, \
inout FMC_hyper1_dqio0, \
inout FMC_hyper1_dqio1, \
inout FMC_hyper1_dqio2, \
inout FMC_hyper1_dqio3, \
inout FMC_hyper1_dqio4, \
inout FMC_hyper1_dqio5, \
inout FMC_hyper1_dqio6, \
inout FMC_hyper1_dqio7, \
inout FMC_hyper1_ck, \
inout FMC_hyper1_ckn, \
inout FMC_hyper1_csn0, \
inout FMC_hyper1_csn1, \
inout FMC_hyper1_rwds, \
inout FMC_hyper1_reset,

`define ila(__name, __signal) \
(* dont_touch = "yes" *) (* mark_debug = "true" *) logic [$bits(__signal)-1:0] __name; \
assign __name = __signal;
Loading