use work.trb_net_std.all;
---REGISTERS within 0..2**(ADDRESS_USED_WIDTH) are handled internally, while all other r/w requests are offered to the parent
---REGISTERS with highest bit set are writeable (CTRL), with highest bit unset are readonly (STAT) from outside and vice versa from inside
---the highest address bit is not used to determine the data position inside REGISTER IN/OUT
---REGISTER_IN is not registered again
INIT_CTRL_REGS : std_logic_vector(2**(3)*32-1 downto 0) :=
(others => '0');
--set to 0 for unused ctrl registers to save resources
- USED_CTRL_REGS : std_logic_vector(2**(3)-1 downto 0) := "11111111";
+ USED_CTRL_REGS : std_logic_vector(2**(3)-1 downto 0) := "00000001";
--set to 0 for each unused bit in a register
USED_CTRL_BITMASK : std_logic_vector(2**(3)*32-1 downto 0) :=
(others => '1');
--no data / address out?
NO_DAT_PORT : std_logic := '0';
+
INIT_ADDRESS : std_logic_vector(15 downto 0) := x"FFFF";
- INIT_UNIQUE_ID : std_logic_vector(95 downto 0) := (others => '0')
+ INIT_UNIQUE_ID : std_logic_vector(95 downto 0) := (others => '0');
+ COMPILE_TIME : std_logic_vector(31 downto 0) := x"00000000";
+ COMPILE_VERSION : std_logic_vector(15 downto 0) := x"0001";
+ HARDWARE_VERSION : std_logic_vector(31 downto 0) := x"12345678"
);
port(
-- Misc
MY_ADDRESS_OUT : out std_logic_vector(15 downto 0);
--Common Register in / out
--- COMMON_STAT_REG_IN : in std_logic_vector(std_COMSTATREG*32-1 downto 0);
--- COMMON_CTRL_REG_OUT : out std_logic_vector(std_COMCTRLREG*32-1 downto 0);
+ COMMON_STAT_REG_IN : in std_logic_vector(std_COMSTATREG*32-1 downto 0);
+ COMMON_CTRL_REG_OUT : out std_logic_vector(std_COMCTRLREG*32-1 downto 0);
--Custom Register in / out
REGISTERS_IN : in std_logic_vector(REGISTER_WIDTH*2**(NUM_STAT_REGS)-1 downto 0);
component trb_net_pattern_gen is
generic (
- WIDTH : integer := NUM_CTRL_REGS
+ WIDTH : integer := 6
);
port(
INPUT_IN : in STD_LOGIC_VECTOR (WIDTH-1 downto 0);
ADDRESS_OUT : out std_logic_vector(15 downto 0)
);
end component;
-
+
+ component trb_net_rom_16x8 is
+ generic(
+ INIT0 : std_logic_vector(15 downto 0) := x"0000";
+ INIT1 : std_logic_vector(15 downto 0) := x"0000";
+ INIT2 : std_logic_vector(15 downto 0) := x"0000";
+ INIT3 : std_logic_vector(15 downto 0) := x"0000";
+ INIT4 : std_logic_vector(15 downto 0) := x"0000";
+ INIT5 : std_logic_vector(15 downto 0) := x"0000";
+ INIT6 : std_logic_vector(15 downto 0) := x"0000";
+ INIT7 : std_logic_vector(15 downto 0) := x"0000"
+ );
+ port(
+ CLK : in std_logic;
+ a : in std_logic_vector(2 downto 0);
+ dout : out std_logic_vector(15 downto 0)
+ );
+ end component;
+
type fsm_state_t is (IDLE, HEADER_RECV, REG_READ, REG_WRITE, ONE_READ, ONE_WRITE, SEND_REPLY_SHORT_TRANSFER,
- MEM_READ, MEM_WRITE, DAT_START_READ, DAT_READ, SEND_REPLY_DATA_finish, ADDRESS_ACK, ADDRESS_RECV);
+ MEM_READ, MEM_WRITE, DAT_START_READ, DAT_READ, SEND_REPLY_DATA_finish, ADDRESS_ACK, ADDRESS_RECV,
+ ROM_READ);
signal current_state, next_state : fsm_state_t;
signal HDR_F1, HDR_F2, HDR_F3 : std_logic_vector(15 downto 0);
signal next_HDR_F1, next_HDR_F2, next_HDR_F3 : std_logic_vector(15 downto 0);
signal buf_REGISTERS_OUT : std_logic_vector(REGISTER_WIDTH*2**(NUM_CTRL_REGS)-1 downto 0);
signal REGISTERS_OUT_write_enable : std_logic_vector(2**(NUM_CTRL_REGS)-1 downto 0);
signal next_REGISTERS_OUT_write_enable : std_logic_vector(2**(NUM_CTRL_REGS)-1 downto 0);
- signal reg_enable_pattern : std_logic_vector(2**(NUM_CTRL_REGS)-1 downto 0);
+ signal reg_enable_pattern : std_logic_vector(63 downto 0);
- signal state_bits : std_logic_vector(2 downto 0);
+ signal next_COMMON_REGISTERS_OUT_write_enable: std_logic_vector(std_COMCTRLREG - 1 downto 0);
+ signal COMMON_REGISTERS_OUT_write_enable : std_logic_vector(std_COMCTRLREG - 1 downto 0);
+ signal buf_COMMON_CTRL_REG_OUT : std_logic_vector(REGISTER_WIDTH*std_COMCTRLREG-1 downto 0);
+ signal state_bits : std_logic_vector(2 downto 0);
signal ADR_SEND_OUT : std_logic;
signal ADR_DATAREADY_IN : std_logic;
signal ADR_REJECTED : std_logic;
signal next_API_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0);
signal buf_API_ERROR_PATTERN_OUT : std_logic_vector(31 downto 0);
-
+ signal rom_read_addr,buf_rom_read_addr : std_logic_vector(2 downto 0);
+ signal rom_read_dout : std_logic_vector(15 downto 0);
begin
pattern_gen_inst : trb_net_pattern_gen
port map(
- INPUT_IN => address(NUM_CTRL_REGS-1 downto 0),
+ INPUT_IN => address(5 downto 0),
RESULT_OUT => reg_enable_pattern
);
buf_API_SEND_OUT, buf_API_PACKET_NUM_OUT, buf_API_DATA_OUT, buf_API_SHORT_TRANSFER_OUT,
REGISTERS_IN, buf_REGISTERS_OUT, reg_enable_pattern, DAT_NO_MORE_DATA_IN,
buf_DAT_DATA_OUT, buf_DAT_ADDR_OUT, DAT_DATAREADY_IN, DAT_DATA_IN, ADR_REJECTED,
- ADR_READ_OUT, ADR_DATAREADY_OUT, ADR_DATA_OUT, ADR_PACKET_NUM_OUT
+ ADR_READ_OUT, ADR_DATAREADY_OUT, ADR_DATA_OUT, ADR_PACKET_NUM_OUT,
+ buf_rom_read_addr, ADR_SEND_OUT, rom_read_dout, COMMON_STAT_REG_IN, buf_COMMON_CTRL_REG_OUT
)
- variable regnum : integer range 0 to 2**(NUM_STAT_REGS)-1;
+ variable regnum : integer range 0 to 63;
begin
next_state <= current_state;
next_HDR_F1 <= HDR_F1;
next_API_SHORT_TRANSFER_OUT <= buf_API_SHORT_TRANSFER_OUT;
next_operation <= saved_operation;
next_REGISTERS_OUT_write_enable <= (others => '0');
+ next_COMMON_REGISTERS_OUT_write_enable <= (others => '0');
next_DAT_READ_ENABLE_OUT <= '0';
next_DAT_WRITE_ENABLE_OUT <= '0';
-
+ rom_read_addr <= buf_rom_read_addr;
regnum := conv_integer(address(NUM_STAT_REGS-1 downto 0));
when ONE_READ => --wait for register address
if API_TYP_IN = TYPE_DAT and API_PACKET_NUM_IN = "01" and API_DATAREADY_IN = '1' then
next_address <= API_DATA_IN;
+ rom_read_addr <= API_DATA_IN(1 downto 0) & '1';
if or_all(API_DATA_IN(ADDRESS_WIDTH-1 downto 8)) = '1' then --data port address
if NO_DAT_PORT = '0' then
next_DAT_READ_ENABLE_OUT <= '1';
else
next_state <= SEND_REPLY_SHORT_TRANSFER;
end if;
- else --register address
+ else
next_state <= REG_READ;
end if;
end if;
when ONE_WRITE => --wait for register address
if API_TYP_IN = TYPE_DAT and API_PACKET_NUM_IN = "01" and API_DATAREADY_IN = '1' then
next_address <= API_DATA_IN;
- if not (API_DATA_IN(15 downto 8)) = x"00" then --data port address
+ if or_all(API_DATA_IN(ADDRESS_WIDTH-1 downto 8)) = '1' then --data port address
if NO_DAT_PORT = '0' then
next_state <= REG_WRITE;
else
next_state <= SEND_REPLY_SHORT_TRANSFER;
end if;
- elsif API_DATA_IN(7) = '1' then --register address
- if API_DATA_IN(6) = '1' then
- if API_DATA_IN(5 downto NUM_CTRL_REGS) = 0 then
- next_state <= REG_WRITE; --ctrl register
- else
- next_state <= SEND_REPLY_SHORT_TRANSFER;
- end if; --unused address - not valid
- else
- if API_DATA_IN(5 downto NUM_STAT_REGS) = 0 then
- next_state <= REG_READ; --stat register - not writing
- else
- next_state <= SEND_REPLY_SHORT_TRANSFER;
- end if; --unused address - not valid
- end if;
- else --status ram address - not valid
+ elsif API_DATA_IN(7 downto 5) = "001" or API_DATA_IN(7 downto 6) = "11" then --ctrl address
+ next_state <= REG_WRITE; --ctrl register
+ else
next_state <= SEND_REPLY_SHORT_TRANSFER;
end if;
end if;
when "11" =>
next_Reg_low <= API_DATA_IN;
if or_all(address(15 downto 8)) = '0' then
- next_REGISTERS_OUT_write_enable <= reg_enable_pattern;
+ if address(7 downto 6) = "11" then
+ next_REGISTERS_OUT_write_enable <= reg_enable_pattern(2**NUM_CTRL_REGS-1 downto 0);
+ else
+ next_COMMON_REGISTERS_OUT_write_enable <= reg_enable_pattern(std_COMCTRLREG-1 downto 0);
+ end if;
next_state <= REG_READ;
else
next_DAT_WRITE_ENABLE_OUT <= '1';
next_API_DATA_OUT <= address;
elsif buf_API_PACKET_NUM_OUT = "01" then
next_API_PACKET_NUM_OUT <= "10";
- if address(6) = '0' then
+ if address(7 downto 6) = "01" then
+ next_API_DATA_OUT <= rom_read_dout;
+ rom_read_addr <= address(1 downto 0) & '0';
+ elsif address(7 downto 6) = "10" then
next_API_DATA_OUT <= REGISTERS_IN(regnum*REGISTER_WIDTH+31 downto regnum*REGISTER_WIDTH+16);
- else
+ elsif address(7 downto 6) = "11" then
next_API_DATA_OUT <= buf_REGISTERS_OUT(regnum*REGISTER_WIDTH+31 downto regnum*REGISTER_WIDTH+16);
+ elsif address(5) = '0' then
+ next_API_DATA_OUT <= COMMON_STAT_REG_IN(regnum*REGISTER_WIDTH+31 downto regnum*REGISTER_WIDTH+16);
+ else --if address(5) = '1' then
+ next_API_DATA_OUT <= buf_COMMON_CTRL_REG_OUT(regnum*REGISTER_WIDTH+31 downto regnum*REGISTER_WIDTH+16);
end if;
elsif buf_API_PACKET_NUM_OUT = "10" then
next_API_PACKET_NUM_OUT <= "11";
- if address(6) = '0' then
+ if address(7 downto 6) = "01" then
+ next_API_DATA_OUT <= rom_read_dout;
+ elsif address(7 downto 6) = "10" then
next_API_DATA_OUT <= REGISTERS_IN(regnum*REGISTER_WIDTH+15 downto regnum*REGISTER_WIDTH);
- else
+ elsif address(7 downto 6) = "11" then
next_API_DATA_OUT <= buf_REGISTERS_OUT(regnum*REGISTER_WIDTH+15 downto regnum*REGISTER_WIDTH);
+ elsif address(5) = '0' then
+ next_API_DATA_OUT <= COMMON_STAT_REG_IN(regnum*REGISTER_WIDTH+15 downto regnum*REGISTER_WIDTH);
+ else --if address(5) = '1' then
+ next_API_DATA_OUT <= buf_COMMON_CTRL_REG_OUT(regnum*REGISTER_WIDTH+15 downto regnum*REGISTER_WIDTH);
end if;
next_state <= SEND_REPLY_DATA_finish;
end if;
end if;
-
when MEM_READ =>
next_state <= SEND_REPLY_SHORT_TRANSFER;
saved_operation <= "0000";
saved_Reg_high <= (others => '0');
saved_Reg_low <= (others => '0');
+ buf_rom_read_addr <= "000";
else
current_state <= next_state;
HDR_F1 <= next_HDR_F1;
buf_DAT_READ_ENABLE_OUT <= next_DAT_READ_ENABLE_OUT;
buf_DAT_WRITE_ENABLE_OUT <= next_DAT_WRITE_ENABLE_OUT;
REGISTERS_OUT_write_enable <= next_REGISTERS_OUT_write_enable;
+ COMMON_REGISTERS_OUT_write_enable <= next_COMMON_REGISTERS_OUT_write_enable;
+ buf_rom_read_addr <= rom_read_addr;
end if;
end if;
end process;
end generate;
end generate;
+ gen_cregout : for i in 0 to std_COMCTRLREG-1 generate
+ gen_cregoutff1 : for j in i*REGISTER_WIDTH to (i+1)*REGISTER_WIDTH-1 generate
+ process(CLK)
+ variable tmp : std_logic_vector(REGISTER_WIDTH-1 downto 0);
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ buf_COMMON_CTRL_REG_OUT(j) <= '0';
+ elsif COMMON_REGISTERS_OUT_write_enable(i) = '1' then
+ tmp := saved_Reg_high & saved_Reg_low;
+ buf_COMMON_CTRL_REG_OUT(j) <= tmp(j-i*REGISTER_WIDTH);
+ end if;
+ end if;
+ end process;
+ end generate;
+ end generate;
+
+ board_rom : trb_net_rom_16x8
+ generic map(
+ INIT0 => COMPILE_TIME(15 downto 0),
+ INIT1 => COMPILE_TIME(31 downto 16),
+ INIT2 => COMPILE_VERSION,
+ INIT3 => (others => '0'),
+ INIT4 => HARDWARE_VERSION(15 downto 0),
+ INIT5 => HARDWARE_VERSION(31 downto 16),
+ INIT6 => (others => '0'),
+ INIT7 => (others => '0')
+ )
+ port map(
+ CLK => CLK,
+ a => rom_read_addr,
+ dout => rom_read_dout
+ );
+
+
buf_API_ERROR_PATTERN_OUT(31 downto 0) <= (others => '0');
API_READ_OUT <= buf_API_READ_OUT;