Integrate CAN controller and implement switches interrupt

This commit is contained in:
2022-12-07 22:35:29 +01:00
parent 2e03702047
commit 7af2c51d61
17 changed files with 346 additions and 22 deletions

View File

@@ -8,7 +8,7 @@ package lt16x32_global is
-- width of the memory, the core supports 32 only
constant memory_width : integer := 32;
-- width of the vector holding the interrupt number, maximum 7 due to processor architecture
constant irq_num_width : integer := 4;
constant irq_num_width : integer := 5;
-- width of the vector holding the interrupt priority, maximum 6 due to processor architecture
constant irq_prio_width : integer := 4;

View File

@@ -30,6 +30,7 @@ package config is
constant CFG_SW : integer := CFG_LED+1;
constant CFG_TIMER : integer := CFG_SW+1;
constant CFG_SCR : integer := CFG_TIMER+1;
constant CFG_CAN : integer := CFG_SCR+1;
-----------------------------
-- base address (BADR) & mask address (MADR)
@@ -42,6 +43,7 @@ package config is
constant CFG_BADR_SW : generic_addr_type := 16#000F0004#;
constant CFG_BADR_TIMER : generic_addr_type := 16#000F0008#;
constant CFG_BADR_SCR : generic_addr_type := 16#000F00A0#;
constant CFG_BADR_CAN : generic_addr_type := 16#000F0100#;
-- mask addr
constant CFG_MADR_ZERO : generic_mask_type := 0;
@@ -52,6 +54,7 @@ package config is
constant CFG_MADR_SW : generic_mask_type := 16#3FFFFF# - (4 - 1); -- size=4 byte
constant CFG_MADR_TIMER : generic_mask_type := 16#3FFFFF# - (8 - 1); -- size=8 byte (2 words)
constant CFG_MADR_SCR : generic_mask_type := 16#3FFFFF# - (8 - 1); -- size=8 byte
constant CFG_MADR_CAN : generic_mask_type := 16#3FFFFF# - (256 - 1); -- size=256 byte
end package config;

View File

@@ -12,6 +12,22 @@ use work.config.all;
package lt16soc_peripherals is
component 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;
irq_on : out std_logic
);
end component can_vhdl_top;
component wb_led is
generic(
memaddr : generic_addr_type;-- := CFG_BADR_LED;
@@ -38,7 +54,9 @@ package lt16soc_peripherals is
wslvo : out wb_slv_out_type;
buttons : in std_logic_vector(4 downto 0);
switches : in std_logic_vector(15 downto 0)
switches : in std_logic_vector(15 downto 0);
interrupt : out std_logic
);
end component;

View File

@@ -19,7 +19,9 @@ entity wb_switches is
wslvo : out wb_slv_out_type;
buttons : in std_logic_vector(4 downto 0);
switches : in std_logic_vector(15 downto 0)
switches : in std_logic_vector(15 downto 0);
interrupt : out std_logic
);
end wb_switches;
@@ -28,6 +30,8 @@ architecture Behavioral of wb_switches is
signal data : std_logic_vector(20 downto 0);
signal ack : std_logic;
signal old_input : std_logic_vector(20 downto 0);
begin
process(clk)
@@ -55,6 +59,26 @@ begin
end if;
end process;
process(clk)
begin
if clk'event and clk='1' then
if rst = '1' then
interrupt <= '0';
old_input <= (others => '0');
else
if buttons & switches /= old_input
then
interrupt <= '1';
else
interrupt <= '0';
end if;
old_input(15 downto 0) <= switches;
old_input(20 downto 16) <= buttons;
end if;
end if;
end process;
wslvo.dat(20 downto 0) <= data;
wslvo.dat(31 downto 21) <= (others=>'0');

View File

@@ -111,13 +111,13 @@ begin
--setup both can nodes
write_regs_from_file( "./testdata/default_setup.tdf", wbs_i1, wbs_o1, clk);
write_regs_from_file( "/home/derek/Git/lt16lab/soc/testbench/testdata/default_setup.tdf", wbs_i1, wbs_o1, clk);
--wait for 1000 ns;
write_regs_from_file( "./testdata/default_setup.tdf", wbs_i2, wbs_o2, clk);
write_regs_from_file( "/home/derek/Git/lt16lab/soc/testbench/testdata/default_setup.tdf", wbs_i2, wbs_o2, clk);
wait for 1000 ns;
--setup and execute a 2 byte transmission in controller 1
write_regs_from_file( "./testdata/data_send.tdf", wbs_i1, wbs_o1, clk);
write_regs_from_file( "/home/derek/Git/lt16lab/soc/testbench/testdata/data_send.tdf", wbs_i1, wbs_o1, clk);
tx_vector(2) <= tx_vector(1);
--manual ack by copying controler 2's ack
@@ -131,7 +131,7 @@ begin
--read status register of controller 1
can_wb_read_reg(wbs_i1, wbs_o1, 2, clk);
--read from controller 2's read buffer
read_regs_with_fileaddr("./testdata/data_read.tdf", "read_data0.tdf", wbs_i2, wbs_o2, clk);
read_regs_with_fileaddr("/home/derek/Git/lt16lab/soc/testbench/testdata/data_read.tdf", "read_data0.tdf", wbs_i2, wbs_o2, clk);
wait for 1200 ns;
--release receive buffer of controller 2
@@ -146,8 +146,8 @@ begin
wait on irq_on2;
--read from both receive buffers
read_regs_with_fileaddr("./testdata/data_read.tdf", "read_data1.tdf", wbs_i1, wbs_o1, clk);
read_regs_with_fileaddr("./testdata/data_read.tdf", "read_data2.tdf", wbs_i2, wbs_o2, clk);
read_regs_with_fileaddr("/home/derek/Git/lt16lab/soc/testbench/testdata/data_read.tdf", "read_data1.tdf", wbs_i1, wbs_o1, clk);
read_regs_with_fileaddr("/home/derek/Git/lt16lab/soc/testbench/testdata/data_read.tdf", "read_data2.tdf", wbs_i2, wbs_o2, clk);
wait for 2400 ns;
--release both receive buffers
can_wb_write_reg(wbs_i1, wbs_o1, 1, "00000100", clk);

72
soc/testbench/project.vhd Normal file
View File

@@ -0,0 +1,72 @@
-- See the file "LICENSE" for the full license governing this code. --
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY project_tb IS
END ENTITY;
ARCHITECTURE sim OF project_tb IS
constant CLK_PERIOD : time := 10 ns;
signal clk : std_logic := '0';
signal rst : std_logic;
signal led : std_logic_vector(7 downto 0);
signal btn : std_logic_vector(4 downto 0) := (others => '0');
signal sw : std_logic_vector(15 downto 0) := (others => '0');
signal anodes : std_logic_vector(7 downto 0);
signal cathodes : std_logic_vector(7 downto 0);
signal can_rx_i : std_logic := '1';
signal can_tx_o : std_logic := '1';
COMPONENT lt16soc_top IS
generic(
programfilename : string := "../../programs/interrupt_test.ram"
);
port(
clk : in std_logic;
rst : in std_logic;
led : out std_logic_vector(7 downto 0);
btn : in std_logic_vector(4 downto 0);
sw : in std_logic_vector(15 downto 0);
anodes : out std_logic_vector(7 downto 0);
cathodes : out std_logic_vector(7 downto 0);
can_rx_i : in std_logic;
can_tx_o : out std_logic
);
END COMPONENT;
BEGIN
dut: lt16soc_top port map(
clk=>clk,
rst=>rst,
led=>led,
btn=>btn,
sw=>sw,
anodes=>anodes,
cathodes=>cathodes,
can_rx_i=>can_rx_i,
can_tx_o=>can_tx_o
);
clk_gen: process
begin
clk <= not clk;
wait for CLK_PERIOD/2;
end process clk_gen;
stimuli: process
begin
rst <= '0';
wait for CLK_PERIOD;
rst <= '1';
wait for 100us;
assert false report "Simulation terminated!" severity failure;
end process stimuli;
END ARCHITECTURE;

View File

@@ -23,6 +23,8 @@ ARCHITECTURE sim OF switches_tb IS
signal buttons: std_logic_vector(4 downto 0);
signal switches : std_logic_vector(15 downto 0);
signal interrupt : std_logic;
signal slvi : wb_slv_in_type;
signal slvo : wb_slv_out_type;
@@ -38,6 +40,7 @@ BEGIN
rst => rst,
buttons => buttons,
switches => switches,
interrupt => interrupt,
wslvi => slvi,
wslvo => slvo
);
@@ -74,6 +77,31 @@ BEGIN
generate_sync_wb_single_read(slvi,slvo,clk,data, SIZE => "01"); -- Half word
wait for 100 ns;
buttons <= "00000";
switches <= x"DEAD";
wait for 50ns;
buttons <= "00100";
switches <= x"DEAD";
wait for 50ns;
buttons <= "00000";
switches <= x"DEAD";
wait for 50ns;
buttons <= "00000";
switches <= x"DAAD";
wait for 50ns;
buttons <= "01000";
switches <= x"DEAD";
wait for 50ns;
buttons <= "00010";
switches <= x"DEAD";
wait for 50ns;
assert false report "Simulation terminated!" severity failure;
end process stimuli;

4
soc/testbench/testdata/data_read.tdf vendored Normal file
View File

@@ -0,0 +1,4 @@
20
21
22
23

5
soc/testbench/testdata/data_send.tdf vendored Normal file
View File

@@ -0,0 +1,5 @@
10 10101010
11 11000010
12 10101010
13 00001111
1 00000001

View File

@@ -0,0 +1,6 @@
4 00000000
5 11111111
6 10000000
7 01001000
8 00000010
0 11111110

View File

@@ -14,7 +14,7 @@ use work.lt16soc_peripherals.all;
entity lt16soc_top is
generic(
programfilename : string := "../../programs/scrolling.ram" -- see "Synthesize XST" process properties for actual value ("-generics" in .xst file)!
programfilename : string := "../../programs/interrupt_test.ram" -- see "Synthesize XST" process properties for actual value ("-generics" in .xst file)!
);
port(
-- clock signal
@@ -28,7 +28,10 @@ port(
sw : in std_logic_vector(15 downto 0);
anodes : out std_logic_vector(7 downto 0);
cathodes : out std_logic_vector(7 downto 0)
cathodes : out std_logic_vector(7 downto 0);
can_rx_i : in std_logic;
can_tx_o : out std_logic
);
end entity lt16soc_top;
@@ -40,7 +43,7 @@ architecture RTL of lt16soc_top is
signal rst_gen : std_logic;
constant slv_mask_vector : std_logic_vector(0 to NWBSLV-1) := b"1111_1100_0000_0001";
constant slv_mask_vector : std_logic_vector(0 to NWBSLV-1) := b"1111_1110_0000_0001";
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"1000";
signal slvo : wb_slv_out_vector := (others=> wbs_out_none);
@@ -180,12 +183,32 @@ begin
addrmask=>CFG_MADR_DMEM)
port map(clk,rst_gen,slvi(CFG_DMEM),slvo(CFG_DMEM));
can_inst : component can_vhdl_top
generic map(
memaddr=>CFG_BADR_CAN,
addrmask=>CFG_MADR_CAN
)
port map(
clk => clk,
rstn => rst,
wbs_i => slvi(CFG_CAN),
wbs_o => slvo(CFG_CAN),
rx_i => can_rx_i,
tx_o => can_tx_o,
irq_on => irq_lines(4)
);
leddev : wb_led
generic map(
CFG_BADR_LED,CFG_MADR_LED
CFG_BADR_LED,
CFG_MADR_LED
)
port map(
clk,rst_gen,led,slvi(CFG_LED),slvo(CFG_LED)
clk,
rst_gen,
led,
slvi(CFG_LED),
slvo(CFG_LED)
);
swdev : wb_switches
@@ -198,10 +221,15 @@ begin
timerdev : wb_timer
generic map(
CFG_BADR_TIMER,CFG_MADR_TIMER
CFG_BADR_TIMER,
CFG_MADR_TIMER
)
port map(
clk,rst_gen,slvi(CFG_TIMER),slvo(CFG_TIMER), irq_lines(3)
clk,
rst_gen,
slvi(CFG_TIMER),
slvo(CFG_TIMER),
irq_lines(3)
);
scrollingdev : wb_scrolling

View File

@@ -81,8 +81,8 @@ set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btn[4]
##Pmod Headers
##Pmod Header JA
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { JA[1] }]; #IO_L20N_T3_A19_15 Sch=ja[1]
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { JA[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { can_rx_i }]; #IO_L20N_T3_A19_15 Sch=ja[1]
set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { can_tx_o }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2]
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { JA[3] }]; #IO_L21P_T3_DQS_15 Sch=ja[3]
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { JA[4] }]; #IO_L18N_T2_A23_15 Sch=ja[4]
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { JA[7] }]; #IO_L16N_T2_A27_15 Sch=ja[7]