Commit c2453b50 authored by Carlos Gil Soriano's avatar Carlos Gil Soriano

Simulation shows that the fsms are correctly working. The fsms work accordingly…

Simulation shows that the fsms are correctly working. The fsms work accordingly ug380 but a whole  reconfiguration through simulation is not feasible due to limitations of ICAP simulation. Added Xilinx's examples for multiboot that, truth to be said, are misleading incomplete for a whole multiboot process (not able to customly rewrite the multiboot and golden bitstream addresses).
parent 35e55b98
......@@ -110,8 +110,10 @@ begin
GBA_ICAP_o <= s_GBA_ICAP;
ICAP_SPARTAN6_inst : ICAP_SPARTAN6
generic map (DEVICE_ID => X"02000093", -- Pre-programmed 'ID code'
SIM_CFG_FILE_NAME => "NONE") -- No simulation possible of ICAP
generic map (-- Pre-programmed 'Device ID code'
DEVICE_ID => to_bitvector(c_DEVICE_ID_XC6SLX45T),
-- No simulation possible of ICAP
SIM_CFG_FILE_NAME => "../rtl/basic_trigger_top.rbt")
port map (BUSY => s_icap_busy, -- 1-bit output Busy/Ready output
O => s_icap_o, -- 16-bit output Configuartion data output bus
CE => s_icap_ce_n, -- 1-bit input Active-Low ICAP Enable input
......@@ -147,6 +149,33 @@ begin
end if;
end process;
--! @brief Process to update the FSM_RUN bit for lock
--! control
--! @param s_ICAP_fsm Main fsm for ICAP
--! @param s_multiboot_fsm subfsm for writes into ICAP
--! @param s_readback_fsm subfsm for reads into ICAP
p_CTR1_FSM_RUN : process (s_ICAP_fsm,
s_multiboot_fsm,
s_readback_fsm)
begin
s_CTR1.FSM_RUN <= '0';
case s_ICAP_fsm is
when R0_RESET =>
s_CTR1.FSM_RUN <= c_CTR1_default.FSM_RUN;
when S1A_MULTIBOOT =>
s_CTR1.FSM_RUN <= '1';
if s_multiboot_fsm = Q0_OK then
s_CTR1.FSM_RUN <= '0';
end if;
when S1B_READBACK =>
s_CTR1.FSM_RUN <= '1';
if s_readback_fsm = Q0_OK then
s_CTR1.FSM_RUN <= '0';
end if;
when others =>
end case;
end process p_CTR1_FSM_RUN;
--! @brief Process to update CTR1
--! @param clk Main clock
p_CTR1: process (clk)
......@@ -156,7 +185,6 @@ begin
s_multiboot_fsm_d0 <= s_multiboot_fsm;
s_readback_fsm_d0 <= s_readback_fsm;
s_CTR1.OP_ACK <= c_CTR1_default.OP_ACK;
s_CTR1.FSM_RUN <= c_CTR1_default.FSM_RUN;
s_CTR1.BAD_OP <= c_CTR1_default.BAD_OP;
s_CTR1.x <= c_CTR1_default.x;
--! Watchout! CTR1 is one-clock delayed
......@@ -180,10 +208,6 @@ begin
s_CTR1.BAD_OP <= '1';
end case;
end if;
when S1A_MULTIBOOT =>
s_CTR1.FSM_RUN <= '1';
when S1B_READBACK =>
s_CTR1.FSM_RUN <= '1';
when others =>
null;
end case;
......@@ -207,6 +231,8 @@ begin
case s_readback_fsm is
when S11A_FETCH_REG =>
s_icap_wr_n <= '1';
when S11B_FETCH_REG =>
s_icap_wr_n <= '1';
when others =>
null;
end case;
......@@ -271,7 +297,9 @@ begin
--! @brief Input port update process for the ICAP primitive
--! @param s_multiboot_fsm subfsm of the multiboot
--! @param s_readback_fsm subfsm of the readback
p_ICAP_write_port: process(s_ICAP_fsm)
p_ICAP_write_port: process(s_ICAP_fsm,
s_multiboot_fsm,
s_readback_fsm)
begin
s_icap_i <= NULL_value;
case s_ICAP_fsm is
......@@ -482,6 +510,8 @@ begin
s_multiboot_fsm <= S4_GEN1_CMD;
when S8_GEN3_CMD =>
s_multiboot_fsm <= S8_GEN3_CMD;
when S12_CMD_CMD =>
s_multiboot_fsm <= S12_CMD_CMD;
when others =>
null;
end case;
......@@ -522,7 +552,7 @@ begin
when S13_IPROG =>
s_multiboot_fsm <= Q0_OK;
when Q0_OK =>
s_multiboot_fsm <= S0_IDLE;
s_multiboot_fsm <= R0_RESET;
when others =>
null;
end case;
......@@ -546,6 +576,9 @@ begin
when OP_WR_GBA =>
v_begin := S8_GEN3_CMD;
v_end := S11_GEN4_ADDR;
when OP_CMD_IPROG =>
v_begin := S12_CMD_CMD;
v_end := Q0_OK;
when others =>
null;
end case;
......@@ -562,6 +595,8 @@ begin
begin
if rising_edge(clk) then
s_multiboot_fsm <= R0_RESET;
v_MBA_slv := f_STD_LOGIC_VECTOR(s_MBA);
v_GBA_slv := f_STD_LOGIC_VECTOR(s_GBA);
case s_ICAP_fsm is
when S1A_MULTIBOOT =>
case s_CTR0_core.OP is
......@@ -571,9 +606,9 @@ begin
s_wr_ICAP_gen1);
order_ICAP(v_MBA_slv(31 downto 16),
s_wr_ICAP_gen2);
order_ICAP(v_MBA_slv(15 downto 0),
order_ICAP(v_GBA_slv(15 downto 0),
s_wr_ICAP_gen3);
order_ICAP(v_MBA_slv(31 downto 16),
order_ICAP(v_GBA_slv(31 downto 16),
s_wr_ICAP_gen4);
when OP_WR_MBA =>
update_wr_general(to_integer(s_CTR0_core.OP));
......@@ -587,6 +622,8 @@ begin
v_GBA_slv := f_STD_LOGIC_VECTOR(s_GBA);
order_ICAP(v_GBA_slv(15 downto 0), s_wr_ICAP_gen3);
order_ICAP(v_GBA_slv(31 downto 16), s_wr_ICAP_gen4);
when OP_CMD_IPROG =>
update_wr_general(to_integer(s_CTR0_core.OP));
when others =>
null;
end case;
......@@ -606,37 +643,46 @@ begin
s_ICAP_fsm <= R0_RESET;
s_CTR0_core <= c_CTR0_default;
else
if s_ICAP_fsm = S0_IDLE
and s_CTR0.PEN = '1' then
--! We should launch and inhibit new operations till finished
if s_CTR1.FSM_RUN = '0' then
s_ICAP_fsm <= R0_RESET;
s_CTR0_core <= s_CTR0;
if s_CTR0.OP = OP_FULLMULTIBOOT
or s_CTR0.OP = OP_WR_MBA
or s_CTR0.OP = OP_WR_GBA then
s_ICAP_fsm <= S1A_MULTIBOOT;
if s_multiboot_fsm = Q0_OK then
s_ICAP_fsm <= R0_RESET;
end if;
case s_ICAP_fsm is
when R0_RESET =>
s_ICAP_fsm <= S0_IDLE;
when S0_IDLE =>
case s_CTR0.PEN is
when '0' =>
s_CTR0_core <= c_CTR0_default;
when others =>
if s_CTR1.FSM_RUN = '0' then
s_CTR0_core <= s_CTR0;
--! In that case we start an operation
if s_CTR0.OP = OP_FULLMULTIBOOT
or s_CTR0.OP = OP_WR_MBA
or s_CTR0.OP = OP_WR_GBA
or s_CTR0.OP = OP_CMD_IPROG then
s_ICAP_fsm <= S1A_MULTIBOOT;
end if;
if s_CTR0.OP = OP_RD_MBA
or s_CTR0.OP = OP_RD_GBA
or s_CTR0.OP = OP_RD_STAT then
s_ICAP_fsm <= S1B_READBACK;
end if;
end if;
end case;
when S1A_MULTIBOOT =>
--! Or we attend that the s_CTR1.FSM_RUN has been
--! deasserted.
if s_multiboot_fsm = Q0_OK then
s_ICAP_fsm <= R0_RESET;
end if;
if s_CTR0.OP = OP_RD_MBA
or s_CTR0.OP = OP_RD_GBA
or s_CTR0.OP = OP_RD_STAT then
s_ICAP_fsm <= S1B_READBACK;
if s_readback_fsm = Q0_OK
or s_readback_fsm = R0_RESET then
s_ICAP_fsm <= R0_RESET;
end if;
when S1B_READBACK =>
--! Or we attend that the s_CTR1.FSM_RUN has been
--! deasserted.
if s_readback_fsm = Q0_OK then
s_ICAP_fsm <= R0_RESET;
end if;
else
s_CTR0_core <= c_CTR0_default;
end if;
else
s_CTR0_core <= c_CTR0_default;
end if;
when others =>
null;
end case;
end if;
else
end if;
end process p_ICAP_fsm;
......
......@@ -5,9 +5,13 @@ use IEEE.NUMERIC_STD.ALL;
package multiboot_pkg is
constant c_MBA_map_addr : STD_LOGIC_VECTOR (23 downto 0) := X"020000";
constant c_GBA_map_addr : STD_LOGIC_VECTOR (23 downto 0) := X"C0FFE5";
constant c_MBA_map_addr : STD_LOGIC_VECTOR (23 downto 0) := X"100000";
constant c_GBA_map_addr : STD_LOGIC_VECTOR (23 downto 0) := X"200000";
--! Please see table 5-13, ug380 pg 80 for a complete list of
--! devices codes
constant c_DEVICE_ID_XC6SLX45T : STD_LOGIC_VECTOR(31 downto 0)
:= X"04028093";
----------------------------------------------------------------------------
-- ICAP configuration data codes
----------------------------------------------------------------------------
......@@ -71,15 +75,16 @@ package multiboot_pkg is
x : STD_LOGIC_VECTOR (7 downto 5);
end record;
attribute a_length of r_CTR0 : type is 32;
attribute a_length of r_CTR0 : type is 8;
constant OP_NONE : UNSIGNED(3 downto 0) := X"0";
constant OP_FULLMULTIBOOT : UNSIGNED(3 downto 0) := X"1";
constant OP_WR_MBA : UNSIGNED(3 downto 0) := X"2";
constant OP_WR_GBA : UNSIGNED(3 downto 0) := X"3";
constant OP_RD_MBA : UNSIGNED(3 downto 0) := X"4";
constant OP_RD_GBA : UNSIGNED(3 downto 0) := X"5";
constant OP_RD_STAT : UNSIGNED(3 downto 0) := X"6";
constant OP_CMD_IPROG : UNSIGNED(3 downto 0) := X"4";
constant OP_RD_MBA : UNSIGNED(3 downto 0) := X"5";
constant OP_RD_GBA : UNSIGNED(3 downto 0) := X"6";
constant OP_RD_STAT : UNSIGNED(3 downto 0) := X"7";
-------------------------------------------------------------------
-- CTR1 register of the control module
......@@ -220,8 +225,9 @@ package multiboot_pkg is
function f_STD_LOGIC_VECTOR (r_register : r_BAR) return STD_LOGIC_VECTOR;
component multiboot_regs is
generic(g_MBA_addr : UNSIGNED(23 downto 0);
g_GBA_addr : UNSIGNED(23 downto 0));
generic(g_MBA_addr : UNSIGNED(23 downto 0);
g_GBA_addr : UNSIGNED(23 downto 0);
g_READ_SPI_OPCODE : STD_LOGIC_VECTOR(7 downto 0));
port(wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
wb_we_i : in STD_LOGIC;
......@@ -330,7 +336,7 @@ package body multiboot_pkg is
--! @brief CTR0 register translation function from r_CTR0 to slv
--! @param r_register slv to be translated
function f_STD_LOGIC_VECTOR (r_register : r_CTR0) return STD_LOGIC_VECTOR is
variable v_return : STD_LOGIC_VECTOR(31 downto 0);
variable v_return : STD_LOGIC_VECTOR(7 downto 0);
begin
v_return(3 downto 0) := STD_LOGIC_VECTOR(r_register.OP);
v_return(4) := r_register.PEN;
......@@ -341,7 +347,7 @@ package body multiboot_pkg is
--! @brief CTR1 register translation function from r_CTR1 to slv
--! @param r_register slv to be translated
function f_STD_LOGIC_VECTOR (r_register : r_CTR1) return STD_LOGIC_VECTOR is
variable v_return : STD_LOGIC_VECTOR(31 downto 0);
variable v_return : STD_LOGIC_VECTOR(7 downto 0);
begin
v_return(0) := r_register.OP_ACK;
v_return(1) := r_register.FSM_RUN;
......
......@@ -28,8 +28,9 @@ use IEEE.NUMERIC_STD.ALL;
use work.multiboot_pkg.ALL;
entity multiboot_regs is
generic(g_MBA_addr : UNSIGNED(23 downto 0);
g_GBA_addr : UNSIGNED(23 downto 0));
generic(g_MBA_addr : UNSIGNED(23 downto 0);
g_GBA_addr : UNSIGNED(23 downto 0);
g_READ_SPI_OPCODE : STD_LOGIC_VECTOR(7 downto 0));
port(wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
wb_we_i : in STD_LOGIC;
......@@ -56,10 +57,20 @@ architecture Behavioral of multiboot_regs is
signal s_CTR0 : r_CTR0 := c_CTR0_default;
signal s_CTR1 : r_CTR1;
signal s_CTR1_d0 : r_CTR1;
signal s_STAT : r_STAT;
signal s_MBA : r_BAR := c_BAR_default;
signal s_GBA : r_BAR := c_BAR_default;
--! SPI_OPCODE can be found in xtp059.pdf slide 25.
--! It corresponds to the instruction it should be performed in
--! the SPI interface, i.e. a read instruction, starting at a
--! given point.
--! This should be checked agains the vendor instruction set for
--! the SPI device.
signal s_MBA : r_BAR := f_BAR( g_READ_SPI_OPCODE
& STD_LOGIC_VECTOR(g_MBA_addr));
signal s_GBA : r_BAR := f_BAR( g_READ_SPI_OPCODE
& STD_LOGIC_VECTOR(g_GBA_addr));
signal s_MBA_ICAP : STD_LOGIC_VECTOR(23 downto 0);
signal s_GBA_ICAP : STD_LOGIC_VECTOR(23 downto 0);
......@@ -114,11 +125,23 @@ begin
s_wb_rty <= '0';
s_wb_err <= '0';
else
s_wb_ack <= '0';
s_wb_rty <= '0';
s_wb_err <= '0';
s_CTR1_d0 <= s_CTR1;
if s_CTR1.FSM_RUN = '0'
and s_CTR1_d0.FSM_RUN = '1' then
--! When we detect that the operation has been already
--! performed, we release the lock.
s_CTR0.PEN <= '0';
end if;
if (wb_stb_i = '1' and wb_cyc_i = '1')
and s_wb_ack = '0'
and s_wb_rty = '0'
and s_wb_err = '0' then
if s_CTR1.FSM_RUN = '0' then
and s_wb_ack = '0'
and s_wb_rty = '0'
and s_wb_err = '0' then
if s_CTR1.FSM_RUN = '1' then
s_wb_err <= '1';
else
case wb_we_i is
......@@ -153,7 +176,7 @@ begin
when others =>
case v_wb_addr is
when CTR0_addr =>
s_CTR0 <= f_CTR0(s_wb_data_i);
s_CTR0 <= f_CTR0(s_wb_data_i(7 downto 0));
s_wb_ack <= '1';
when c_MBA_addr =>
s_MBA <= f_BAR(s_wb_data_i);
......@@ -166,10 +189,8 @@ begin
end case;
end case;
end if;
else
end if;
end if;
else
end if;
end process;
......
......@@ -8,7 +8,13 @@ use work.multiboot_pkg.ALL;
entity multiboot_top is
generic(g_MBA_addr : UNSIGNED (23 downto 0) := UNSIGNED(c_MBA_map_addr);
g_GBA_addr : UNSIGNED (23 downto 0) := UNSIGNED(c_GBA_map_addr));
g_GBA_addr : UNSIGNED (23 downto 0) := UNSIGNED(c_GBA_map_addr);
--! This is a vendor-dependant SPI opcode.
--! Pleasem take a look to the flash memory manual and put here
--! the op-code/instruction-code for a read operation over SPI
--! i.e. for m25p32 memory that corresponds to X"03"
--! Set it up accordingly.
g_READ_SPI_OPCODE : STD_LOGIC_VECTOR(7 downto 0) := X"03");
port(wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
wb_we_i : in STD_LOGIC;
......@@ -37,8 +43,9 @@ signal s_GBA_addr : STD_LOGIC_VECTOR(23 downto 0);
begin
multiboot_regs_inst : multiboot_regs
generic map (g_MBA_addr => g_MBA_addr,
g_GBA_addr => g_GBA_addr)
generic map (g_MBA_addr => g_MBA_addr,
g_GBA_addr => g_GBA_addr,
g_READ_SPI_OPCODE => g_READ_SPI_OPCODE)
port map(wb_rst_i => wb_rst_i,
wb_clk => wb_clk,
wb_we_i => wb_we_i,
......
......@@ -16,7 +16,9 @@ package multiboot_pkg_tb is
-- Component Declaration
component multiboot_top is
generic(g_MBA_addr : UNSIGNED (23 downto 0) := UNSIGNED(c_MBA_map_addr);
g_GBA_addr : UNSIGNED (23 downto 0) := UNSIGNED(c_GBA_map_addr));
g_GBA_addr : UNSIGNED (23 downto 0) := UNSIGNED(c_GBA_map_addr);
--! Read operation code for a m25p32 memory
g_READ_SPI_OPCODE : STD_LOGIC_VECTOR(7 downto 0) := X"03");
port(
wb_rst_i : in STD_LOGIC;
wb_clk : in STD_LOGIC;
......
......@@ -167,7 +167,7 @@ begin
v_CTR0.PEN := '1';
v_CTR0.x := (others => '0');
v_CTR0_slv := f_STD_LOGIC_VECTOR(v_CTR0);
write_wb_addr(STD_LOGIC_VECTOR(CTR0_addr), v_CTR0_slv);
write_wb_addr(STD_LOGIC_VECTOR(CTR0_addr), X"000000"&v_CTR0_slv);
end procedure;
-- procedure checker_and_logger() is
......@@ -231,22 +231,41 @@ begin
rst;
--! Testbench procedure
--! 1.- OP_NONE operation
write_check_operation(OP_NONE);
wait for c_WB_CLK_PERIOD*35000;
wait until rising_edge(wb_clk);
-- --! Testbench procedure
-- --! 1.- OP_NONE operation
-- write_check_operation(OP_NONE);
--! 2.- OP_FULLMULTIBOOT operation
write_check_operation(OP_FULLMULTIBOOT);
wait for c_WB_CLK_PERIOD*100;
wait until rising_edge(wb_clk);
--! 3.- OP_WR_MBA operation
write_check_operation(OP_WR_MBA);
wait for c_WB_CLK_PERIOD*100;
wait until rising_edge(wb_clk);
--! 4.- OP_WR_GBA operation
write_check_operation(OP_WR_GBA);
--! 5.- OP_RD_MBA operation
wait for c_WB_CLK_PERIOD*100;
wait until rising_edge(wb_clk);
--! 5.- OP_CMD_IPROG operation
write_check_operation(OP_CMD_IPROG);
wait for c_WB_CLK_PERIOD*100;
wait until rising_edge(wb_clk);
--! 6.- OP_RD_MBA operation
write_check_operation(OP_RD_MBA);
--! 6.- OP_RD_GBA operation
wait for c_WB_CLK_PERIOD*100;
wait until rising_edge(wb_clk);
--! 7.- OP_RD_GBA operation
write_check_operation(OP_RD_GBA);
--! 7.- OP_RD_STAT operation
wait for c_WB_CLK_PERIOD*100;
wait until rising_edge(wb_clk);
--! 8.- OP_RD_STAT operation
write_check_operation(OP_RD_STAT);
wait for c_WB_CLK_PERIOD*100;
wait until rising_edge(wb_clk);
wait for c_WB_CLK_PERIOD*2000;
wait until rising_edge(wb_clk);
assert false report "No error. Simulation ends." severity failure;
end process tb;
......
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