From 2cef3005cd6eb1e6f4ca069ee5d797959b46c381 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 11 Sep 2019 10:59:13 +0100 Subject: [PATCH] fpga: Hookup nexys-video to litedram Signed-off-by: Benjamin Herrenschmidt --- fpga/nexys-video.xdc | 228 +++++++++++++++++++++++++++++++++++++- fpga/top-nexys-video.vhdl | 207 ++++++++++++++++++++++++++++++++++ microwatt.core | 21 +++- 3 files changed, 452 insertions(+), 4 deletions(-) create mode 100644 fpga/top-nexys-video.vhdl diff --git a/fpga/nexys-video.xdc b/fpga/nexys-video.xdc index 239376f..aa840c7 100644 --- a/fpga/nexys-video.xdc +++ b/fpga/nexys-video.xdc @@ -3,8 +3,232 @@ create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS15} [get_ports ext_rst] -set_property -dict {PACKAGE_PIN AA19 IOSTANDARD LVCMOS33} [get_ports uart0_txd] -set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports uart0_rxd] +set_property -dict {PACKAGE_PIN AA19 IOSTANDARD LVCMOS33} [get_ports uart_main_tx] +set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports uart_main_rx] + +##Pmod Header JA: UART (bottom) + +set_property -dict { PACKAGE_PIN Y21 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_cts_n }]; +set_property -dict { PACKAGE_PIN AA21 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_tx }]; +set_property -dict { PACKAGE_PIN AA20 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_rx }]; +set_property -dict { PACKAGE_PIN AA18 IOSTANDARD LVCMOS33 } [get_ports { uart_pmod_rts_n }]; + +# LEDs (no colors, just normal LEDs here) +set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { led0 }]; +set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led1 }]; + +# DRAM (generated by LiteX) + ## ddram:0.a +set_property LOC M2 [get_ports ddram_a[0]] +set_property SLEW FAST [get_ports ddram_a[0]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[0]] + ## ddram:0.a +set_property LOC M5 [get_ports ddram_a[1]] +set_property SLEW FAST [get_ports ddram_a[1]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[1]] + ## ddram:0.a +set_property LOC M3 [get_ports ddram_a[2]] +set_property SLEW FAST [get_ports ddram_a[2]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[2]] + ## ddram:0.a +set_property LOC M1 [get_ports ddram_a[3]] +set_property SLEW FAST [get_ports ddram_a[3]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[3]] + ## ddram:0.a +set_property LOC L6 [get_ports ddram_a[4]] +set_property SLEW FAST [get_ports ddram_a[4]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[4]] + ## ddram:0.a +set_property LOC P1 [get_ports ddram_a[5]] +set_property SLEW FAST [get_ports ddram_a[5]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[5]] + ## ddram:0.a +set_property LOC N3 [get_ports ddram_a[6]] +set_property SLEW FAST [get_ports ddram_a[6]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[6]] + ## ddram:0.a +set_property LOC N2 [get_ports ddram_a[7]] +set_property SLEW FAST [get_ports ddram_a[7]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[7]] + ## ddram:0.a +set_property LOC M6 [get_ports ddram_a[8]] +set_property SLEW FAST [get_ports ddram_a[8]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[8]] + ## ddram:0.a +set_property LOC R1 [get_ports ddram_a[9]] +set_property SLEW FAST [get_ports ddram_a[9]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[9]] + ## ddram:0.a +set_property LOC L5 [get_ports ddram_a[10]] +set_property SLEW FAST [get_ports ddram_a[10]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[10]] + ## ddram:0.a +set_property LOC N5 [get_ports ddram_a[11]] +set_property SLEW FAST [get_ports ddram_a[11]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[11]] + ## ddram:0.a +set_property LOC N4 [get_ports ddram_a[12]] +set_property SLEW FAST [get_ports ddram_a[12]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[12]] + ## ddram:0.a +set_property LOC P2 [get_ports ddram_a[13]] +set_property SLEW FAST [get_ports ddram_a[13]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[13]] + ## ddram:0.a +set_property LOC P6 [get_ports ddram_a[14]] +set_property SLEW FAST [get_ports ddram_a[14]] +set_property IOSTANDARD SSTL15 [get_ports ddram_a[14]] + ## ddram:0.ba +set_property LOC L3 [get_ports ddram_ba[0]] +set_property SLEW FAST [get_ports ddram_ba[0]] +set_property IOSTANDARD SSTL15 [get_ports ddram_ba[0]] + ## ddram:0.ba +set_property LOC K6 [get_ports ddram_ba[1]] +set_property SLEW FAST [get_ports ddram_ba[1]] +set_property IOSTANDARD SSTL15 [get_ports ddram_ba[1]] + ## ddram:0.ba +set_property LOC L4 [get_ports ddram_ba[2]] +set_property SLEW FAST [get_ports ddram_ba[2]] +set_property IOSTANDARD SSTL15 [get_ports ddram_ba[2]] + ## ddram:0.ras_n +set_property LOC J4 [get_ports ddram_ras_n] +set_property SLEW FAST [get_ports ddram_ras_n] +set_property IOSTANDARD SSTL15 [get_ports ddram_ras_n] + ## ddram:0.cas_n +set_property LOC K3 [get_ports ddram_cas_n] +set_property SLEW FAST [get_ports ddram_cas_n] +set_property IOSTANDARD SSTL15 [get_ports ddram_cas_n] + ## ddram:0.we_n +set_property LOC L1 [get_ports ddram_we_n] +set_property SLEW FAST [get_ports ddram_we_n] +set_property IOSTANDARD SSTL15 [get_ports ddram_we_n] + ## ddram:0.dm +set_property LOC G3 [get_ports ddram_dm[0]] +set_property SLEW FAST [get_ports ddram_dm[0]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dm[0]] + ## ddram:0.dm +set_property LOC F1 [get_ports ddram_dm[1]] +set_property SLEW FAST [get_ports ddram_dm[1]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dm[1]] + ## ddram:0.dq +set_property LOC G2 [get_ports ddram_dq[0]] +set_property SLEW FAST [get_ports ddram_dq[0]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[0]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[0]] + ## ddram:0.dq +set_property LOC H4 [get_ports ddram_dq[1]] +set_property SLEW FAST [get_ports ddram_dq[1]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[1]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[1]] + ## ddram:0.dq +set_property LOC H5 [get_ports ddram_dq[2]] +set_property SLEW FAST [get_ports ddram_dq[2]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[2]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[2]] + ## ddram:0.dq +set_property LOC J1 [get_ports ddram_dq[3]] +set_property SLEW FAST [get_ports ddram_dq[3]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[3]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[3]] + ## ddram:0.dq +set_property LOC K1 [get_ports ddram_dq[4]] +set_property SLEW FAST [get_ports ddram_dq[4]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[4]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[4]] + ## ddram:0.dq +set_property LOC H3 [get_ports ddram_dq[5]] +set_property SLEW FAST [get_ports ddram_dq[5]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[5]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[5]] + ## ddram:0.dq +set_property LOC H2 [get_ports ddram_dq[6]] +set_property SLEW FAST [get_ports ddram_dq[6]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[6]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[6]] + ## ddram:0.dq +set_property LOC J5 [get_ports ddram_dq[7]] +set_property SLEW FAST [get_ports ddram_dq[7]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[7]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[7]] + ## ddram:0.dq +set_property LOC E3 [get_ports ddram_dq[8]] +set_property SLEW FAST [get_ports ddram_dq[8]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[8]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[8]] + ## ddram:0.dq +set_property LOC B2 [get_ports ddram_dq[9]] +set_property SLEW FAST [get_ports ddram_dq[9]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[9]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[9]] + ## ddram:0.dq +set_property LOC F3 [get_ports ddram_dq[10]] +set_property SLEW FAST [get_ports ddram_dq[10]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[10]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[10]] + ## ddram:0.dq +set_property LOC D2 [get_ports ddram_dq[11]] +set_property SLEW FAST [get_ports ddram_dq[11]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[11]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[11]] + ## ddram:0.dq +set_property LOC C2 [get_ports ddram_dq[12]] +set_property SLEW FAST [get_ports ddram_dq[12]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[12]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[12]] + ## ddram:0.dq +set_property LOC A1 [get_ports ddram_dq[13]] +set_property SLEW FAST [get_ports ddram_dq[13]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[13]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[13]] + ## ddram:0.dq +set_property LOC E2 [get_ports ddram_dq[14]] +set_property SLEW FAST [get_ports ddram_dq[14]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[14]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[14]] + ## ddram:0.dq +set_property LOC B1 [get_ports ddram_dq[15]] +set_property SLEW FAST [get_ports ddram_dq[15]] +set_property IOSTANDARD SSTL15 [get_ports ddram_dq[15]] +set_property IN_TERM UNTUNED_SPLIT_50 [get_ports ddram_dq[15]] + ## ddram:0.dqs_p +set_property LOC K2 [get_ports ddram_dqs_p[0]] +set_property SLEW FAST [get_ports ddram_dqs_p[0]] +set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_p[0]] + ## ddram:0.dqs_p +set_property LOC E1 [get_ports ddram_dqs_p[1]] +set_property SLEW FAST [get_ports ddram_dqs_p[1]] +set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_p[1]] + ## ddram:0.dqs_n +set_property LOC J2 [get_ports ddram_dqs_n[0]] +set_property SLEW FAST [get_ports ddram_dqs_n[0]] +set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_n[0]] + ## ddram:0.dqs_n +set_property LOC D1 [get_ports ddram_dqs_n[1]] +set_property SLEW FAST [get_ports ddram_dqs_n[1]] +set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_dqs_n[1]] + ## ddram:0.clk_p +set_property LOC P5 [get_ports ddram_clk_p] +set_property SLEW FAST [get_ports ddram_clk_p] +set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_clk_p] + ## ddram:0.clk_n +set_property LOC P4 [get_ports ddram_clk_n] +set_property SLEW FAST [get_ports ddram_clk_n] +set_property IOSTANDARD DIFF_SSTL15 [get_ports ddram_clk_n] + ## ddram:0.cke +set_property LOC J6 [get_ports ddram_cke] +set_property SLEW FAST [get_ports ddram_cke] +set_property IOSTANDARD SSTL15 [get_ports ddram_cke] + ## ddram:0.odt +set_property LOC K4 [get_ports ddram_odt] +set_property SLEW FAST [get_ports ddram_odt] +set_property IOSTANDARD SSTL15 [get_ports ddram_odt] + ## ddram:0.reset_n +set_property LOC G1 [get_ports ddram_reset_n] +set_property SLEW FAST [get_ports ddram_reset_n] +set_property IOSTANDARD SSTL15 [get_ports ddram_reset_n] + +#Internal VREF +set_property INTERNAL_VREF 0.750 [get_iobanks 35] set_property CONFIG_VOLTAGE 3.3 [current_design] set_property CFGBVS VCCO [current_design] diff --git a/fpga/top-nexys-video.vhdl b/fpga/top-nexys-video.vhdl new file mode 100644 index 0000000..ea23dd5 --- /dev/null +++ b/fpga/top-nexys-video.vhdl @@ -0,0 +1,207 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library unisim; +use unisim.vcomponents.all; + +library work; +use work.wishbone_types.all; + +entity toplevel is + generic ( + MEMORY_SIZE : positive := 16384; + RAM_INIT_FILE : string := "firmware.hex"; + RESET_LOW : boolean := true; + CLK_FREQUENCY : positive := 100000000; + USE_LITEDRAM : boolean := false; + DISABLE_FLATTEN_CORE : boolean := false + ); + port( + ext_clk : in std_ulogic; + ext_rst : in std_ulogic; + + -- UART0 signals: + uart_main_tx : out std_ulogic; + uart_main_rx : in std_ulogic; + + -- LEDs + led0 : out std_logic; + led1 : out std_logic; + + -- DRAM wires + ddram_a : out std_logic_vector(14 downto 0); + ddram_ba : out std_logic_vector(2 downto 0); + ddram_ras_n : out std_logic; + ddram_cas_n : out std_logic; + ddram_we_n : out std_logic; + ddram_dm : out std_logic_vector(1 downto 0); + ddram_dq : inout std_logic_vector(15 downto 0); + ddram_dqs_p : inout std_logic_vector(1 downto 0); + ddram_dqs_n : inout std_logic_vector(1 downto 0); + ddram_clk_p : out std_logic; + ddram_clk_n : out std_logic; + ddram_cke : out std_logic; + ddram_odt : out std_logic; + ddram_reset_n : out std_logic + ); +end entity toplevel; + +architecture behaviour of toplevel is + + -- Reset signals: + signal soc_rst : std_ulogic; + signal pll_rst : std_ulogic; + + -- Internal clock signals: + signal system_clk : std_ulogic; + signal system_clk_locked : std_ulogic; + + -- DRAM wishbone connection + signal wb_dram_in : wishbone_master_out; + signal wb_dram_out : wishbone_slave_out; + signal wb_dram_csr : std_ulogic; + signal wb_dram_init : std_ulogic; + + -- Control/status + signal core_alt_reset : std_ulogic; + +begin + + -- Main SoC + soc0: entity work.soc + generic map( + MEMORY_SIZE => MEMORY_SIZE, + RAM_INIT_FILE => RAM_INIT_FILE, + RESET_LOW => RESET_LOW, + SIM => false, + HAS_DRAM => USE_LITEDRAM, + DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE + ) + port map ( + system_clk => system_clk, + rst => soc_rst, + uart0_txd => uart_main_tx, + uart0_rxd => uart_main_rx, + wb_dram_in => wb_dram_in, + wb_dram_out => wb_dram_out, + wb_dram_csr => wb_dram_csr, + wb_dram_init => wb_dram_init, + alt_reset => core_alt_reset + ); + + nodram: if not USE_LITEDRAM generate + signal ddram_clk_dummy : std_ulogic; + begin + reset_controller: entity work.soc_reset + generic map( + RESET_LOW => RESET_LOW + ) + port map( + ext_clk => ext_clk, + pll_clk => system_clk, + pll_locked_in => system_clk_locked, + ext_rst_in => ext_rst, + pll_rst_out => pll_rst, + rst_out => soc_rst + ); + + clkgen: entity work.clock_generator + generic map( + CLK_INPUT_HZ => 100000000, + CLK_OUTPUT_HZ => CLK_FREQUENCY + ) + port map( + ext_clk => ext_clk, + pll_rst_in => pll_rst, + pll_clk_out => system_clk, + pll_locked_out => system_clk_locked + ); + + led0 <= '1'; + led1 <= not soc_rst; + core_alt_reset <= '0'; + + -- Vivado barfs on those differential signals if left + -- unconnected. So instanciate a diff. buffer and feed + -- it a constant '0'. + dummy_dram_clk: OBUFDS + port map ( + O => ddram_clk_p, + OB => ddram_clk_n, + I => ddram_clk_dummy + ); + ddram_clk_dummy <= '0'; + + end generate; + + has_dram: if USE_LITEDRAM generate + signal dram_init_done : std_ulogic; + signal dram_init_error : std_ulogic; + signal soc_rst_0 : std_ulogic; + signal soc_rst_1 : std_ulogic; + begin + + -- Eventually dig out the frequency from the generator + -- but for now, assert it's 100Mhz + assert CLK_FREQUENCY = 100000000; + + reset_controller: entity work.soc_reset + generic map( + RESET_LOW => RESET_LOW + ) + port map( + ext_clk => ext_clk, + pll_clk => system_clk, + pll_locked_in => system_clk_locked, + ext_rst_in => ext_rst, + pll_rst_out => pll_rst, + rst_out => soc_rst_0 + ); + + dram: entity work.litedram_wrapper + generic map( + DRAM_ABITS => 25, + DRAM_ALINES => 15 + ) + port map( + clk_in => ext_clk, + rst => pll_rst, + system_clk => system_clk, + system_reset => soc_rst_1, + pll_locked => system_clk_locked, + + wb_in => wb_dram_in, + wb_out => wb_dram_out, + wb_is_csr => wb_dram_csr, + wb_is_init => wb_dram_init, + + serial_tx => open, + serial_rx => '0', + + init_done => dram_init_done, + init_error => dram_init_error, + + ddram_a => ddram_a, + ddram_ba => ddram_ba, + ddram_ras_n => ddram_ras_n, + ddram_cas_n => ddram_cas_n, + ddram_we_n => ddram_we_n, + ddram_cs_n => open, + ddram_dm => ddram_dm, + ddram_dq => ddram_dq, + ddram_dqs_p => ddram_dqs_p, + ddram_dqs_n => ddram_dqs_n, + ddram_clk_p => ddram_clk_p, + ddram_clk_n => ddram_clk_n, + ddram_cke => ddram_cke, + ddram_odt => ddram_odt, + ddram_reset_n => ddram_reset_n + ); + + led0 <= dram_init_done and not dram_init_error; + led1 <= dram_init_error; -- Make it blink ? + soc_rst <= soc_rst_0 or soc_rst_1; + + end generate; +end architecture behaviour; diff --git a/microwatt.core b/microwatt.core index 9e60792..f7002ae 100644 --- a/microwatt.core +++ b/microwatt.core @@ -76,7 +76,7 @@ filesets: files: - fpga/nexys-video.xdc : {file_type : xdc} - fpga/clk_gen_plle2.vhd : {file_type : vhdlSource-2008} - - fpga/top-generic.vhdl : {file_type : vhdlSource-2008} + - fpga/top-nexys-video.vhdl : {file_type : vhdlSource-2008} arty_a7: files: @@ -107,7 +107,7 @@ targets: vivado: {part : xc7a100tcsg324-1} toplevel : toplevel - nexys_video: + nexys_video-nodram: default_tool: vivado filesets: [core, nexys_video, soc, fpga, debug_xilinx] parameters : @@ -120,6 +120,19 @@ targets: vivado: {part : xc7a200tsbg484-1} toplevel : toplevel + nexys_video: + default_tool: vivado + filesets: [core, nexys_video, soc, fpga, debug_xilinx, litedram] + parameters: + - memory_size + - ram_init_file + - use_litedram=true + - disable_flatten_core + generate: [dram_nexys_video] + tools: + vivado: {part : xc7a200tsbg484-1} + toplevel : toplevel + arty_a7-35-nodram: default_tool: vivado filesets: [core, arty_a7, soc, fpga, debug_xilinx] @@ -197,6 +210,10 @@ generate: generator: litedram_gen parameters: {board : arty} + dram_nexys_video: + generator: litedram_gen + parameters: {board : nexys-video} + parameters: memory_size: datatype : int