Files
lt16lab/soc/peripheral/can_vhdl_top.vhd
Thomas Fehmel 657a54ba18 Initial Commit
2016-10-18 14:21:45 +02:00

139 lines
3.6 KiB
VHDL

--
-- can_vhdl_top
--
-- Wraps the verilog component for the con controller into an VHDL entity
-- The wrapper translates the 8-bit wishbone interface into an 32 bit interface.
-- Still, only 8-bit accesses are allowed.
-- @autor: Thoams Fehmel
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
library work;
use work.wishbone.all;
use work.config.all;
entity can_vhdl_top is
generic(
memaddr : generic_addr_type;
addrmask : generic_mask_type
);
port(
clk : in std_logic;
rstn : in std_logic;
wbs_i : in wb_slv_in_type;
wbs_o : out wb_slv_out_type;
rx_i : in std_logic;
tx_o : out std_logic;
driver_en : out std_logic;
irq_on : out std_logic
);
end can_vhdl_top;
architecture Behavioral of can_vhdl_top is
component can_top is
port(
wb_clk_i : in std_logic;
wb_rst_i : in std_logic;
wb_dat_i : in std_logic_vector(7 downto 0);
wb_dat_o : out std_logic_vector(7 downto 0);
wb_cyc_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_adr_i : in std_logic_vector(7 downto 0);
wb_ack_o : out std_logic;
clk_i : in std_logic;
rx_i : in std_logic;
tx_o : out std_logic;
bus_off_on : out std_logic;
irq_on : out std_logic;
clkout_o : out std_logic
);
end component;
signal wb_dat_i : std_logic_vector(7 downto 0);
signal wb_dat_o : std_logic_vector(7 downto 0);
signal wb_addr : std_logic_vector(7 downto 0);
signal bus_off_on : std_logic;
signal clkout_o : std_logic;
signal irq_can : std_logic;
signal irq_tmp : std_logic;
signal tx_int : std_logic;
begin
can_mod : can_top
port map(
wb_clk_i=>clk,
wb_rst_i=>rstn,
wb_dat_i=>wb_dat_i,
wb_dat_o=>wb_dat_o,
wb_cyc_i=>wbs_i.cyc,
wb_stb_i=>wbs_i.stb,
wb_we_i=>wbs_i.we,
wb_adr_i=>wb_addr,
wb_ack_o=>wbs_o.ack,
clk_i=>clk,
rx_i=>rx_i,
tx_o=>tx_int,
bus_off_on=>bus_off_on, --goes nowhere
irq_on=>irq_can,
clkout_o=>clkout_o --goes nowhere
);
wb_dat_i <=
wbs_i.dat(31 downto 24) when wbs_i.sel = "1000" else
wbs_i.dat(23 downto 16) when wbs_i.sel = "0100" else
wbs_i.dat(15 downto 8) when wbs_i.sel = "0010" else
wbs_i.dat( 7 downto 0) when wbs_i.sel = "0001" else
(others=>'0');
--assert (wbs_i.stb='0' or ((wbs_i.sel="1000") or (wbs_i.sel="0100") or (wbs_i.sel="0010") or (wbs_i.sel="0001") or (wbs_i.sel="0000"))) report "CAN wishbone itnerface only supports 8-bit accesses" severity ERROR;
wbs_o.dat(31 downto 24) <= wb_dat_o when wbs_i.sel(3) = '1' else (others=>'0');
wbs_o.dat(23 downto 16) <= wb_dat_o when wbs_i.sel(2) = '1' else (others=>'0');
wbs_o.dat(15 downto 8) <= wb_dat_o when wbs_i.sel(1) = '1' else (others=>'0');
wbs_o.dat( 7 downto 0) <= wb_dat_o when wbs_i.sel(0) = '1' else (others=>'0');
--wb_addr <= wbs_i.adr(WB_ADR_BOUND+6 downto WB_ADR_BOUND) & sel2adr(wbs_i.sel);
addr_adder: if to_unsigned(memaddr, 16)(7 downto 2) /= "000000" generate
wb_addr <= std_logic_vector(unsigned(wbs_i.adr(7 downto 2) & sel2adr(wbs_i.sel)) - to_unsigned(memaddr, 16)(7 downto 0));
end generate;
addr_forw: if to_unsigned(memaddr, 16)(7 downto 2) = "000000" generate
wb_addr(7 downto 2) <= wbs_i.adr(7 downto 2);
wb_addr(1 downto 0) <= sel2adr(wbs_i.sel);
end generate;
--convert irq : active low(can) to activ high(soc)
--interrupt generation: only active for one clk cycle after falling edge of irq_can
irq_gen: process(clk)
begin
if clk = '1' and clk'event then
if irq_tmp = '1' and irq_can = '0' then
irq_on <= '1';
else
irq_on <= '0';
end if;
irq_tmp <= irq_can;
end if;
end process;
--NOTE: address check is skipped udner the assumption that the interconnect handles it.
wbs_o.wbcfg <= wb_membar(memaddr, addrmask);
-- driver enable
tx_o <= tx_int;
driver_en <= not(tx_int);
end architecture;