Commit 6d999ff9 authored by marvin.damschen's avatar marvin.damschen Committed by Marvin Damschen
Browse files

Integrate CommandQueue into VC707 design

- copy leon3 files to prepare cmdque pipeline hold

- wire cmdqu_iu_stall_reqh to iu3 to enable pipeline stalling by cmdque

- disable leon3cg and leon3sh in synthesis
parent 9cf2a6b9
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library grlib;
use grlib.stdlib.all;
library ces;
use ces.cmdqueuelib.all;
library techmap;
use techmap.gencomp.syncfifo_2p;
entity CmdQueue is
generic(
qu_tech : integer := 2;
qu_abits : integer := 6
);
port(
clk : in std_ulogic;
rstn : std_ulogic;
cmdqui : in CmdQueue_in_type;
cmdquo : out CmdQueue_out_type;
mmioo : out mmio_cmdqu_type;
icapi : out icap_in_type;
icapo : in icap_out_type
);
end CmdQueue;
architecture behavioral of CmdQueue is
type cmdfifo_in_type is record
rstn : std_ulogic;
renable : std_ulogic;
wenable : std_ulogic;
cmd_in : std_logic_vector(31 downto 0);
end record cmdfifo_in_type;
type cmdfifo_out_type is record
empty : std_ulogic;
full : std_ulogic;
cmdcount: std_logic_vector(qu_abits - 1 downto 0);
head : std_logic_vector(31 downto 0);
end record cmdfifo_out_type;
type state_type is ( STATE_RST,
STATE_FECMD,
STATE_DEC,
STATE_STALL,
STATE_ABORT_ICAP,
STATE_ABORT_ICAP_SETUP,
STATE_EXE_CFG_BTS_SETUP,
STATE_EXE_CFG_BTS,
STATE_EXE_UPD_SSM,
STATE_EXE_SET_IU_STALL_STATE,
STATE_EXE_CLR_CMDQU_SETUP,
STATE_EXE_CLR_CMDQU,
STATE_EXE_IRQ,
STATE_EXE_SET_ST_BASE_ADDR);
type reg_type is record
state : state_type;
nxtstate : state_type;
cycle_cnt : unsigned(2 downto 0);
cmdqui : CmdQueue_in_type;
cmdquo : CmdQueue_out_type;
mmioo : mmio_cmdqu_type;
icapi : icap_in_type;
icapi_datain_prev: std_logic_vector(31 downto 0);
icapo_state : std_logic_vector(7 downto 4);
icapo_error_state_change : std_ulogic;
icapo_desynch : std_ulogic;
icapo_state_err: std_ulogic; -- 1 => stop, 0 => continue
crn_cmd : std_logic_vector(31 downto 0);
st_addr_nxt : unsigned(31 downto 0);
st_addr_prev : std_logic_vector(31 downto 0);
st_base_addr : std_logic_vector(31 downto 24);
end record reg_type;
-- r2 -> two cycles latency
signal r, r2, rin :reg_type := (state => STATE_FECMD, nxtstate => STATE_FECMD,
cycle_cnt => "000",
cmdqui => (wenable => '0', cmd_in => (others => '0'),
hready => '0', holdaddr => '1', lostbus => '0', st_dataout => (others => '0')),
cmdquo => (cmdqu_status => (others => '0'), iu_stall_reqh => '0',
irq => '0', st_ahb => '0', st_enable => '0',
st_addr => (others => '0')),
mmioo => (ssm_wenable => '0', ssm_addr => (others => '0'),
ssm_data => (others => '0')),
st_addr_nxt => (others => '0'), st_addr_prev => (others => '0'),
icapi => (enclkn => '1', writen => '1', datain => (others => '0')),
icapi_datain_prev => (others => '0'),
icapo_state => (others => '0'), icapo_desynch => '0',icapo_error_state_change => '0', icapo_state_err => '0',
crn_cmd => (others => '0'), st_base_addr => (others => '0') );
signal cmdfifo_in : cmdfifo_in_type;
signal cmdfifo_out : cmdfifo_out_type;
constant CMDQU_STATUS_CMDCOUNT_LOWER_BOUND : natural := 16;
constant CMDQU_STATUS_CMDCOUNT_UPPER_BOUND : natural := 15+qu_abits;
begin
cmd_fifo : syncfifo_2p
generic map( tech => qu_tech, abits => qu_abits, dbits => 32, fwft => 0)
port map ( clk, cmdfifo_in.rstn, cmdfifo_in.rstn, cmdfifo_in.renable,
cmdfifo_out.full,cmdfifo_out.empty, open,cmdfifo_out.cmdcount,
cmdfifo_out.head, clk, cmdfifo_in.wenable,
open, open, open, open, cmdfifo_in.cmd_in);
sequential : process(clk, rstn)
begin
if rising_edge(clk) then
if rstn = '0' then
r.state <= STATE_RST;
else
r2 <= r;
r <= rin;
end if;
end if;
end process sequential;
combinational : process(cmdqui, rstn, icapo, cmdfifo_out, r, r2)
variable v : reg_type;
begin
v := r;
cmdfifo_in.rstn <= rstn;
cmdfifo_in.renable <= '0';
cmdfifo_in.wenable <= '0';
v.icapi.enclkn := '1';
v.icapi.writen := '1';
v.mmioo.ssm_wenable := '0';
v.mmioo.ssm_addr := (others => '0');
v.mmioo.ssm_data := (others => '0');
v.cmdquo.st_enable := '0';
v.cmdquo.irq := '0';
v.icapo_state := icapo.dataout(7 downto 4);
v.icapo_desynch := '0';
v.cmdqui := cmdqui;
if r2.cmdqui.lostbus = '1' then -- the latched addr is no longer latched, we need to drive it again
-- it will take at least two cycles so we can read the value from r2
v.cmdquo.st_addr := r2.st_addr_prev;
elsif v.cmdqui.holdaddr = '0' then
v.cmdquo.st_addr := std_logic_vector(r.st_addr_nxt);
end if;
v.st_addr_prev := r.cmdquo.st_addr;
v.st_addr_nxt := unsigned(v.cmdquo.st_addr) + 4;
case r.state is
when STATE_FECMD =>
v.crn_cmd := (others => '0');
v.cmdquo.st_addr := (others => '0');
v.cmdquo.st_ahb := '0';
if cmdfifo_out.empty = '0' then
cmdfifo_in.renable <= '1';
v.nxtstate := STATE_DEC;
else
v.nxtstate := STATE_FECMD;
end if;
when STATE_DEC =>
v.nxtstate := STATE_DEC;
if r.crn_cmd(cmd_type'range) = "0000" then
v.crn_cmd := cmdfifo_out.head;
else
case r.crn_cmd(cmd_type'range) is
when CMD_CFG_BTS => v.nxtstate := STATE_EXE_CFG_BTS_SETUP;
when CMD_UPD_SSM => v.nxtstate := STATE_EXE_UPD_SSM;
when CMD_SET_IU_STALL_STATE => v.nxtstate := STATE_EXE_SET_IU_STALL_STATE;
when CMD_STALL_CMDQU => v.nxtstate := STATE_STALL;
when CMD_STALL_CMDQU_IM => v.nxtstate := STATE_STALL;
when CMD_CLR_CMDQU => v.nxtstate := STATE_EXE_CLR_CMDQU_SETUP;
when CMD_CLR_CMDQU_IM => v.nxtstate := STATE_EXE_CLR_CMDQU_SETUP;
when CMD_IRQ => v.nxtstate := STATE_EXE_IRQ;
when CMD_SET_ST_BASE_ADDR => v.nxtstate := STATE_EXE_SET_ST_BASE_ADDR;
when CMD_RST_IM => v.nxtstate := STATE_RST;
when CMD_RSM_CMDQU_IM => v.nxtstate := STATE_FECMD;
when CMD_ABORT_ICAP_IM => v.nxtstate := STATE_ABORT_ICAP_SETUP;
when others =>
--pragma translate_off
assert false report "CmdQueue: Encountered illegal instruction" severity error;
--pragma translate_on
v.nxtstate := STATE_FECMD;
end case;
end if;
when STATE_EXE_CFG_BTS_SETUP =>
v.cmdquo.st_addr(23 downto 0) := r2.crn_cmd(23 downto 0);
v.cmdquo.st_addr(31 downto 24) := r2.st_base_addr;
v.st_addr_nxt := unsigned(v.cmdquo.st_addr);
v.cmdquo.st_ahb := r2.crn_cmd(24);
v.icapi.writen := '0';
v.nxtstate := STATE_EXE_CFG_BTS;
when STATE_EXE_CFG_BTS =>
v.nxtstate := STATE_EXE_CFG_BTS;
v.icapi.writen := '0';
if r.icapo_state_err = '1' then
v.icapi.enclkn := '1';
v.cmdquo.st_enable := '0';
v.cmdquo.st_ahb := '0';
v.cmdquo.irq := r2.crn_cmd(26);
if r2.crn_cmd(27) = '1' then
v.cmdquo.iu_stall_reqh := '0';
end if;
v.nxtstate := STATE_STALL;
elsif r2.icapo_desynch = '1' then
v.icapi.enclkn := '1';
v.cmdquo.st_enable := '0';
v.nxtstate := STATE_FECMD;
else
v.cmdquo.st_enable := '1';
if v.cmdqui.hready = '1' then
v.icapi.enclkn := '0';
end if;
end if;
when STATE_EXE_UPD_SSM =>
v.mmioo.ssm_wenable := '1';
v.mmioo.ssm_addr := r2.crn_cmd(27 downto 18);
v.mmioo.ssm_data := r2.crn_cmd(17 downto 0);
v.nxtstate := STATE_FECMD;
when STATE_EXE_SET_IU_STALL_STATE =>
v.cmdquo.iu_stall_reqh := r2.crn_cmd(0);
v.nxtstate := STATE_FECMD;
when STATE_EXE_CLR_CMDQU_SETUP =>
v.cycle_cnt := "000";
v.nxtstate := STATE_EXE_CLR_CMDQU;
when STATE_EXE_IRQ =>
v.cmdquo.irq := '1';
v.nxtstate := STATE_FECMD;
when STATE_EXE_SET_ST_BASE_ADDR =>
v.st_base_addr := r2.crn_cmd(7 downto 0);
v.nxtstate := STATE_FECMD;
when STATE_STALL =>
v.nxtstate := STATE_STALL;
when STATE_ABORT_ICAP_SETUP =>
v.icapi.datain := (others => '0');
v.cycle_cnt := "000";
v.icapi.enclkn := '0';
v.icapi.writen := '0';
v.nxtstate := STATE_ABORT_ICAP;
when STATE_ABORT_ICAP =>
v.icapi.datain := (others => '0');
v.icapi.enclkn := '0';
v.icapi.writen := '1';
if r.cycle_cnt = "011" then
v.nxtstate := STATE_STALL;
else
v.cycle_cnt := r.cycle_cnt + 1;
v.nxtstate := STATE_ABORT_ICAP;
end if;
when STATE_EXE_CLR_CMDQU =>
cmdfifo_in.rstn <= '0';
if r.cycle_cnt = "100" then
v.nxtstate := STATE_FECMD;
else
v.cycle_cnt := r.cycle_cnt + 1;
v.nxtstate := STATE_EXE_CLR_CMDQU;
end if;
when STATE_RST =>
cmdfifo_in.rstn <= rstn; -- to clear queue use the cmd, but in case of
-- a systemwide reset this state will clear it too
v.cmdquo.iu_stall_reqh := '0';
v.st_base_addr := (others => '0');
v.nxtstate := STATE_FECMD;
end case;
-- immediate cmd's
if r2.cmdqui.wenable = '1' then
if r2.cmdqui.cmd_in(31) = '1' then
v.crn_cmd := r2.cmdqui.cmd_in;
v.nxtstate := STATE_DEC;
else -- is queueable
cmdfifo_in.wenable <= '1';
end if;
end if;
v.icapi.datain := v.cmdqui.st_dataout;
v.cmdquo.cmdqu_status := (others => '0');
v.cmdquo.cmdqu_status(31 downto 24) := r2.st_base_addr;
v.cmdquo.cmdqu_status(CMDQU_STATUS_CMDCOUNT_UPPER_BOUND downto CMDQU_STATUS_CMDCOUNT_LOWER_BOUND) := cmdfifo_out.cmdcount;
--v.cmdquo.cmdqu_status(22 downto 16) := cmdfifo_out.cmdcount;
v.cmdquo.cmdqu_status(15 downto 12) := r2.icapo_state;
v.cmdquo.cmdqu_status(3) := cmdfifo_out.full;
v.cmdquo.cmdqu_status(2) := r2.cmdquo.iu_stall_reqh;
if r2.state = STATE_STALL then v.cmdquo.cmdqu_status(1) := '1';
else v.cmdquo.cmdqu_status(1) := '0'; end if;
v.cmdquo.cmdqu_status(0) := not cmdfifo_out.empty;
if r2.state /= STATE_FECMD then v.cmdquo.cmdqu_status(0) := '1'; end if;
if r.icapi.datain = DESYNCH and r.icapi_datain_prev = CMD_PACKET then
v.icapo_desynch := '1';
end if;
if r.icapi.enclkn = '0' then
v.icapi_datain_prev := r.icapi.datain;
end if;
-- 0xd -> 0x5 -> 0x1 => cfgerr => abort
-- 0x1 ->* 0x5 ->* 0xd => new bitstream => continue
-- 0xd = 1101
-- 0x1 = 0001
-- 0x5 = 0101
v.icapo_state_err := '0';
v.icapo_error_state_change := '0';
if r2.icapo_state = "0101" then
v.icapo_error_state_change := '1';
end if;
if r.icapo_error_state_change = '1' and r2.icapo_state(7) = '0' then
v.icapo_state_err := '1';
end if;
icapi <= v.icapi;
cmdquo <= v.cmdquo;
cmdquo.iu_stall_reqh <= r2.cmdquo.iu_stall_reqh;
cmdquo.cmdqu_status <= r2.cmdquo.cmdqu_status;
cmdquo.irq <= r2.cmdquo.irq;
mmioo <= r2.mmioo;
cmdfifo_in.cmd_in <= r2.cmdqui.cmd_in;
v.state := v.nxtstate;
rin <= v;
end process combinational;
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library ces;
package cmdqueuelib is
component large_syncram_dp is
generic (
blkabits : integer := 14;
blkcnt : integer := 3;
bramabits: integer := 16;
tech : integer := 2;
dbits : integer := 32
);
port (
clk1 : in std_ulogic;
addr1 : in std_logic_vector((bramabits -1) downto 0);
datain1 : in std_logic_vector((dbits -1) downto 0);
dataout1 : out std_logic_vector((dbits -1) downto 0);
enable1 : in std_ulogic;
write1 : in std_ulogic;
clk2 : in std_ulogic;
addr2 : in std_logic_vector((bramabits -1) downto 0);
datain2 : in std_logic_vector((dbits -1) downto 0);
dataout2 : out std_logic_vector((dbits -1) downto 0);
enable2 : in std_ulogic;
write2 : in std_ulogic
);
end component;
type icap_out_type is record
dataout: std_logic_vector(31 downto 0);
end record icap_out_type;
type icap_in_type is record
enclkn : std_ulogic;
writen : std_ulogic;
datain : std_logic_vector(31 downto 0);
end record icap_in_type;
type CmdQueue_out_type is record
cmdqu_status : std_logic_vector(31 downto 0);
iu_stall_reqh : std_ulogic;
irq : std_ulogic;
st_ahb : std_ulogic;
st_enable : std_ulogic;
st_addr : std_logic_vector(31 downto 0);
end record CmdQueue_out_type;
-- icap_in_type
type CmdQueue_in_type is record
cmd_in : std_logic_vector(31 downto 0);
wenable : std_ulogic;
st_dataout : std_logic_vector(31 downto 0);
hready : std_ulogic;
holdaddr : std_ulogic;
lostbus : std_ulogic;
end record CmdQueue_in_type;
type mmio_cmdqu_type is record
ssm_wenable : std_ulogic;
ssm_addr : std_logic_vector(9 downto 0);
ssm_data : std_logic_vector(17 downto 0);
end record;
constant CMD_PACKET : std_logic_vector(31 downto 0) := x"0C000180"; -- Type 1 packet write 1 words to CMD
constant DESYNCH : std_logic_vector(31 downto 0) := x"000000B0"; -- END of a partial bit file (bit swapped)
-- immediate cmds, identified by their "IM" suffix, have
-- their MSB bit set to 1, others to 0.
-- Some commands can be issued in both modes, marked by their
-- "QIM" suffix
subtype cmd_type is std_logic_vector(31 downto 28);
constant CMD_CLR_CMDQU : cmd_type := "0001"; -- clears the CmdStore
constant CMD_CLR_CMDQU_IM : cmd_type := "1001"; -- clears the CmdStore
-- Configure bitstream
-- (27) => 0|1 stall CMDQUEUE & RESUMEIU on CRC Error
-- (26) => 0|1 stall CMDQUEUE & IRQ on CRC Error
-- (24) => 0|1 (ahb read with ST_BASE_ADDR),
-- (23 to 0) => bitstream addr
constant CMD_CFG_BTS : cmd_type := "0010"; -- configure bitstream
-- update SSM entry for SIID in previously set SIGRP
-- 27 to 18 => SIID,
-- 17 to 0 => new SSM entry
constant CMD_UPD_SSM : cmd_type := "0011";
-- 0 => 0 resume, 0 => 1 stall (raises cmdquo.iu_stall_reqh)
constant CMD_SET_IU_STALL_STATE : cmd_type := "0100";
-- stalls the CmdQueue Fetch->Dec->Exe cycle, immediate cmds still work
constant CMD_STALL_CMDQU : cmd_type := "0101";
constant CMD_STALL_CMDQU_IM : cmd_type := "1101";
-- trigger interrupt upon execution, (e.g. put it as the last cmd )
constant CMD_IRQ : cmd_type := "0110";
-- if the bitstream needs to be read from bus you need to pass
-- the higher 8 Bits via this command first, since the CMD_CFG_BTS command
-- has only place for 24 Bits of the addr.
-- this value is latched and remains as the used
-- ST (STORE) base address until overwritten by another or a reset
-- command was executed
-- (7 to 0) => main memory base addr
constant CMD_SET_ST_BASE_ADDR : cmd_type := "0111";
constant CMD_RSM_CMDQU_IM : cmd_type := "1011";
-- if you wish to abort a running reconfiguration this cmd will
-- do the work, it will initiate a SelectMAP ABORT sequence as
-- described in ug470_7Series_Config.pdf pp. 47
constant CMD_ABORT_ICAP_IM : cmd_type := "1111";
-- resets all latched registers, such as stall requests or st_base_addr
-- and other internal stuff. Doesn't clear the CmdStore except if a
-- systemwide reset was triggered by pulling the RSTN pin up for more than four
-- cycles.
constant CMD_RST_IM : cmd_type := "1110";
component CmdQueue is
generic(
qu_tech : integer := 20;
qu_abits : integer := 4
);
port(
clk : in std_ulogic;
rstn : std_ulogic;
cmdqui : in CmdQueue_in_type;
cmdquo : out CmdQueue_out_type;
icapi : out icap_in_type;
icapo : in icap_out_type;
mmioo : out mmio_cmdqu_type
);
end component;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real."**";
library grlib;
use grlib.stdlib.all;
use grlib.amba.all;
use grlib.devices.all;
library gaisler;
use gaisler.misc.all;
library techmap;
use techmap.gencomp.all;
library ces;
use ces.CmdQueuelib.all;
library unisim;
use unisim.vcomponents.all;
--pragma translate_off
library std;
use std.textio.all;
use ieee.std_logic_textio.all;
--pragma translate_on
entity CmdQueue_TOP is
generic (
-- queue control slave
hsindex : integer := -1;
hmindex : integer := -1;
haddr : integer := -1;
hmask : integer := 16#FFF#;
hirq : integer := -1;
tech : integer := 2;
qu_abits : integer := -1
);
port (
clk : in std_ulogic;
rstn : in std_ulogic;
cmdqu_iu_stall_reqh : out std_ulogic;
cmdqu_mmioo : out mmio_cmdqu_type;
quctl_ahbsi : in ahb_slv_in_type;
quctl_ahbso : out ahb_slv_out_type;
ahbmi : in ahb_mst_in_type;
ahbmo : out ahb_mst_out_type
);
end CmdQueue_TOP;
architecture beh of CmdQueue_TOP is
constant hsconfig : ahb_config_type := (
0 => ahb_device_reg (VENDOR_CONTRIB, CONTRIB_CORE2, 0, 16#D#, hirq),
4 => ahb_membar(haddr, '0', '0', hmask),
others => zero32
);
constant hmconfig : ahb_config_type := (
0 => ahb_device_reg (VENDOR_CONTRIB, CONTRIB_CORE2, 0, 16#C#, 0),
others => zero32
);
type cmdqu_bitst_state_type is (AHBM_IDLE, BITSTORE_READ_ADDR_WAIT, BITSTORE_READ, AHBM_BUSREQ, AHBM_SINGLE, AHBM_ADDRWAIT, AHBM_READ);
constant bitst_blkabits : integer := 14;
constant bitst_blkcnt : integer := 6;
constant bitst_bramabits : integer:= 17; -- (integer( ceil( log2(real(bitst_blkcnt))))) + bitst_blkabits;
constant bitst_size : integer := bitst_blkcnt*(2**bitst_blkabits)*4;
type bitst_in_type is record
addr : std_logic_vector((bitst_bramabits - 1) downto 0);
datain : std_logic_vector(31 downto 0);
enable : std_ulogic;
write : std_ulogic;
end record;
signal bitst_dataout1, bitst_dataout2 : std_logic_vector(31 downto 0);
signal bitst_in1, bitst_in2 : bitst_in_type := (addr => (others => '0'), datain => zero32,
enable => '0', write => '0');
signal cmdqui : CmdQueue_in_type;
signal cmdquo : CmdQueue_out_type;
--signal mmioo : mmio_cmdqu_type;
signal icap_cmdqui : icap_in_type;
signal icap_cmdquo : icap_out_type;
type cmdqu_bitst_reg_type is record
state : cmdqu_bitst_state_type;
nxtstate : cmdqu_bitst_state_type;
st_enable : std_ulogic;
st_ahb : std_ulogic;
hready : std_ulogic;
hgrant : std_ulogic;
hrdata : std_logic_vector(31 downto 0);
burst : std_logic_vector(2 downto 0);
beatcnt : unsigned(2 downto 0);
lostbus : std_ulogic;
end record;
type ahb_bitst_reg_type is record
tocmdqueue : std_ulogic;
bitst_in_addr: std_logic_vector((bitst_bramabits + 1) downto 2);
hwrite : std_ulogic;
hsel : std_ulogic;
end record;
signal ahbs_r, ahbs_rin : ahb_bitst_reg_type := (tocmdqueue => '0', bitst_in_addr => (others => '0'),
hwrite => '0', hsel => '0');
signal qubs_r, qubs_rin : cmdqu_bitst_reg_type := (state => AHBM_IDLE, nxtstate => AHBM_IDLE, st_enable => '0',
st_ahb => '0', hready => '0', hgrant => '0', hrdata => (others => '0'),
burst => "000", beatcnt => "000", lostbus => '0');