Commit fcca65bf authored by Tristan Gingold's avatar Tristan Gingold

Add wb_xc7_fw_update module.

As a generic module to update xc7 firmware.
parent 6f2c1dbd
......@@ -196,6 +196,8 @@ Directory [modules/wishbone](modules/wishbone) contains modules for wishbone.
- [wb_vic](modules/wishbone/wb_vic) is the vectored interrupt controller.
- [wb_ds182x_readout](modules/wishbone/wb_ds182x_readout) is a direct
interface to the digital thermometer.
- [wb_xc7_fw_update](modules/wishbone/wb_xc7_fw_update) is an SPI interface
to drive the xc7 bitstream spi flash (using the ht-flash tool).
* There are utilities to handle a wishbone bus:
- [wb_clock_crossing](modules/wishbone/wb_clock_crossing) handle clock domain
......
modules = { "local" : [
"wb_async_bridge",
"wb_axi4lite_bridge",
......@@ -30,6 +29,7 @@ modules = { "local" : [
"wb_indirect",
"wbgen2",
"wbgenplus",
"wb_xc7_fw_update",
]}
files = [
......
files = ["wb_xc7_fw_update_regs.vhd",
"xwb_xc7_fw_update.vhd",
]
memory-map:
bus: wb-32-be
name: wb_xc7_fw_update_regs
description: System Control Registers
x-hdl:
busgroup: True
children:
- reg:
name: far
width: 32
access: rw
comment: Flash Access Register
description: Provides direct access to the SPI flash memory containing the bitstream.
x-hdl:
type: wire
write-strobe: true
children:
- field:
name: data
range: 7-0
comment: SPI Data
description: Data to be written / read to/from the flash SPI controller.
- field:
name: xfer
range: 8
comment: SPI Start Transfer
description: "write 1: initiate an SPI transfer with an 8-bit data word taken from the DATA field. write 0: no effect"
- field:
name: ready
range: 9
comment: SPI Ready
description: "read 1: Core is ready to initiate another transfer. DATA field contains the data read during previous transaction. read 0: core is busy"
- field:
name: cs
range: 10
comment: SPI Chip Select
description: "write 1: Enable target SPI controller. write 0: Disable target SPI controller"
-- Do not edit. Generated on Tue May 19 11:16:59 2020 by tgingold
-- With Cheby 1.4.dev0 and these options:
-- -i wb_xc7_fw_update_regs.cheby --gen-hdl wb_xc7_fw_update_regs.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
entity wb_xc7_fw_update_regs is
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
-- Flash Access Register
-- SPI Data
far_data_i : in std_logic_vector(7 downto 0);
far_data_o : out std_logic_vector(7 downto 0);
-- SPI Start Transfer
far_xfer_i : in std_logic;
far_xfer_o : out std_logic;
-- SPI Ready
far_ready_i : in std_logic;
far_ready_o : out std_logic;
-- SPI Chip Select
far_cs_i : in std_logic;
far_cs_o : out std_logic;
far_wr_o : out std_logic
);
end wb_xc7_fw_update_regs;
architecture syn of wb_xc7_fw_update_regs is
signal rd_req_int : std_logic;
signal wr_req_int : std_logic;
signal rd_ack_int : std_logic;
signal wr_ack_int : std_logic;
signal wb_en : std_logic;
signal ack_int : std_logic;
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal far_wreq : std_logic;
signal rd_ack_d0 : std_logic;
signal rd_dat_d0 : std_logic_vector(31 downto 0);
signal wr_req_d0 : std_logic;
signal wr_dat_d0 : std_logic_vector(31 downto 0);
signal wr_sel_d0 : std_logic_vector(3 downto 0);
begin
-- WB decode signals
wb_en <= wb_i.cyc and wb_i.stb;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wb_rip <= '0';
else
wb_rip <= (wb_rip or (wb_en and not wb_i.we)) and not rd_ack_int;
end if;
end if;
end process;
rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wb_wip <= '0';
else
wb_wip <= (wb_wip or (wb_en and wb_i.we)) and not wr_ack_int;
end if;
end if;
end process;
wr_req_int <= (wb_en and wb_i.we) and not wb_wip;
ack_int <= rd_ack_int or wr_ack_int;
wb_o.ack <= ack_int;
wb_o.stall <= not ack_int and wb_en;
wb_o.rty <= '0';
wb_o.err <= '0';
-- pipelining for wr-in+rd-out
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
rd_ack_int <= '0';
wr_req_d0 <= '0';
else
rd_ack_int <= rd_ack_d0;
wb_o.dat <= rd_dat_d0;
wr_req_d0 <= wr_req_int;
wr_dat_d0 <= wb_i.dat;
wr_sel_d0 <= wb_i.sel;
end if;
end if;
end process;
-- Register far
far_data_o <= wr_dat_d0(7 downto 0);
far_xfer_o <= wr_dat_d0(8);
far_ready_o <= wr_dat_d0(9);
far_cs_o <= wr_dat_d0(10);
far_wr_o <= far_wreq;
-- Process for write requests.
process (wr_req_d0) begin
far_wreq <= '0';
-- Reg far
far_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
end process;
-- Process for read requests.
process (rd_req_int, far_data_i, far_xfer_i, far_ready_i, far_cs_i) begin
-- By default ack read requests
rd_dat_d0 <= (others => 'X');
-- Reg far
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= far_data_i;
rd_dat_d0(8) <= far_xfer_i;
rd_dat_d0(9) <= far_ready_i;
rd_dat_d0(10) <= far_cs_i;
rd_dat_d0(31 downto 11) <= (others => '0');
end process;
end syn;
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.vcomponents.all;
use work.wishbone_pkg.all;
entity xwb_xc7_fw_update is
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out;
flash_cs_n_o : out std_logic;
flash_mosi_o : out std_logic;
flash_miso_i : in std_logic
);
end xwb_xc7_fw_update;
architecture rtl of xwb_xc7_fw_update is
signal far_data_in : std_logic_vector(7 downto 0);
signal far_data_out : std_logic_vector(7 downto 0);
signal far_xfer_out : std_logic;
signal far_ready_in : std_logic;
signal far_cs_out : std_logic;
signal far_wr_out : std_logic;
signal flash_spi_cs : std_logic;
signal flash_spi_start : std_logic;
signal flash_spi_wdata : std_logic_vector(7 downto 0);
signal flash_sclk : std_logic;
begin
inst_regs: entity work.wb_xc7_fw_update_regs
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
wb_i => wb_i,
wb_o => wb_o,
far_data_i => far_data_in,
far_data_o => far_data_out,
far_xfer_i => '0',
far_xfer_o => far_xfer_out,
far_ready_i => far_ready_in,
far_ready_o => open,
far_cs_i => '0',
far_cs_o => far_cs_out,
far_wr_o => far_wr_out
);
-- Need to capture cs and data_out, and need to delay start.
p_host_spi_registers : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
flash_spi_start <= '0';
flash_spi_wdata <= (others => '0');
flash_spi_cs <= '0';
elsif far_wr_out = '1' then
flash_spi_wdata <= far_data_out;
flash_spi_start <= far_xfer_out;
flash_spi_cs <= far_cs_out;
else
-- Pulse for start.
flash_spi_start <= '0';
end if;
end if;
end process;
U_SPI_Master : entity work.gc_simple_spi_master
generic map (
g_div_ratio_log2 => 0,
g_num_data_bits => 8)
port map (
clk_sys_i => clk_i,
rst_n_i => rst_n_i,
cs_i => flash_spi_cs,
start_i => flash_spi_start,
cpol_i => '0',
data_i => flash_spi_wdata,
ready_o => far_ready_in,
data_o => far_data_in,
spi_cs_n_o => flash_cs_n_o,
spi_sclk_o => flash_sclk,
spi_mosi_o => flash_mosi_o,
spi_miso_i => flash_miso_i);
STARTUPE2_inst : STARTUPE2
generic map (
PROG_USR => "FALSE", -- Activate program event security feature. Requires encrypted bitstreams.
SIM_CCLK_FREQ => 0.0 -- Set the Configuration Clock Frequency(ns) for simulation.
)
port map (
CFGCLK => open, -- 1-bit output: Configuration main clock output
CFGMCLK => open, -- 1-bit output: Configuration internal oscillator clock output
EOS => open, -- 1-bit output: Active high output signal indicating the End Of Startup.
PREQ => open, -- 1-bit output: PROGRAM request to fabric output
CLK => '0', -- 1-bit input: User start-up clock input
GSR => '0', -- 1-bit input: Global Set/Reset input (GSR cannot be used for the port name)
GTS => '0', -- 1-bit input: Global 3-state input (GTS cannot be used for the port name)
KEYCLEARB => '0', -- 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
PACK => '0', -- 1-bit input: PROGRAM acknowledge input
USRCCLKO => flash_sclk, -- 1-bit input: User CCLK input
USRCCLKTS => '0', -- 1-bit input: User CCLK 3-state enable input
USRDONEO => '0', -- 1-bit input: User DONE pin output control
USRDONETS => '1' -- 1-bit input: User DONE 3-state enable output
);
end rtl;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment