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

Binary file not shown.

Binary file not shown.

71
programs/can_test.prog_ Normal file
View File

@@ -0,0 +1,71 @@
reset:
br always >main
nop
hardfault:
reti
nop
memfault:
reti
nop
timer_interrupt:
reti
nop
can_interrupt:
br >can_interrupt
nop
.align
led_addr: .word 0x000F0000
timer_counter_addr: .word 0x000F0008
timer_status_addr: .word 0x000F000C
dmem_start_addr: .word 0x00000400
dmem_end_addr: .word 0x000004FC
priority_mask: .word 0xFFFFFF03
timer_target_value: .word 127 // for simulation
// timer_target_value: .word 0xF10000 // for real board
can_base_addr: .word 0x000F0100
can_control_ptr: .word =can_base_addr
can_command_ptr: .word =can_base_addr + 1
can_acceptance_code_ptr: .word =can_base_addr + 4
can_acceptance_mask_ptr: .word =can_base_addr + 5
can_acceptance_bus_timing0_ptr: .word =can_base_addr + 6
can_acceptance_bus_timing1_ptr: .word =can_base_addr + 7
can_output_control_ptr: .word =can_base_addr + 8
can_identifier0_ptr: .word =can_base_addr + 10
can_identifier1_ptr: .word =can_base_addr + 11
can_data0_ptr: .word =can_base_addr + 12
can_data1_ptr: .word =can_base_addr + 13
main:
// Initialize stack pointer to the end of the data memory
ldr r12, >dmem_end_addr
// Set runtime priority
ldr r0, >priority_mask
and r14, r0, r14
// Set LED to pattern
clr r2
addi r2, 0x7A
st08 r0, r2
// Initialize CAN
ldr r0, >can_acceptance_code_ptr
loop:
br >loop
nop
can_interrupt:
reti
nop

View File

@@ -0,0 +1,65 @@
reset:
br always >main
nop
hardfault:
reti
nop
memfault:
reti
nop
switches_interrupt:
br >switches_interrupt_handler
nop
can_interrupt:
br >can_interrupt_handler
nop
.align
led_addr: .word 0x000F0000
timer_counter_addr: .word 0x000F0008
timer_status_addr: .word 0x000F000C
dmem_start_addr: .word 0x00000400
dmem_end_addr: .word 0x000004FC
priority_mask: .word 0xFFFFFF03
// timer_target_value: .word 127 // for simulation
timer_target_value: .word 0xF10000 // for real board
main:
// Initialize stack pointer to the end of the data memory
ldr r12, >dmem_end_addr
// Set runtime priority
ldr r0, >priority_mask
and r14, r0, r14
ldr r0,>led_addr // LED addr
ldr r1,>timer_status_addr // Timer addr
ldr r3,>timer_counter_addr // Timer addr
// Set LED to pattern
clr r2
addi r2, 0x7A
st08 r0, r2
// Enable the timer...
ldr r2, >timer_target_value
st32 r3, r2
clr r2
addi r2, 0x1 // enable bit set
st32 r1, r2
loop:
br >loop
nop
timer_interrupt_handler:
// Set LED to pattern
clr r2
addi r2, 0x0C
st08 r0, r2

View File

@@ -12,11 +12,11 @@ nop
scrolling_addr: .word 0x000F00A0 scrolling_addr: .word 0x000F00A0
scrolling_count_addr: .word 0x000F00A4 scrolling_count_addr: .word 0x000F00A4
scrolling_cnt_value: .word 0x20FC000 // for real board // scrolling_cnt_value: .word 0x20FC000 // for real board
// scrolling_cnt_value: .word 0x500 // for simulation scrolling_cnt_value: .word 0x500 // for simulation
w_cnt_top: .word 0x3FC000 // for real board // w_cnt_top: .word 0x3FC000 // for real board
// w_cnt_top: .word 0x100 //for simulation w_cnt_top: .word 0x100 //for simulation
pattern_ptr: .word =pattern1 pattern_ptr: .word =pattern1

View File

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

View File

@@ -30,6 +30,7 @@ package config is
constant CFG_SW : integer := CFG_LED+1; constant CFG_SW : integer := CFG_LED+1;
constant CFG_TIMER : integer := CFG_SW+1; constant CFG_TIMER : integer := CFG_SW+1;
constant CFG_SCR : integer := CFG_TIMER+1; constant CFG_SCR : integer := CFG_TIMER+1;
constant CFG_CAN : integer := CFG_SCR+1;
----------------------------- -----------------------------
-- base address (BADR) & mask address (MADR) -- 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_SW : generic_addr_type := 16#000F0004#;
constant CFG_BADR_TIMER : generic_addr_type := 16#000F0008#; constant CFG_BADR_TIMER : generic_addr_type := 16#000F0008#;
constant CFG_BADR_SCR : generic_addr_type := 16#000F00A0#; constant CFG_BADR_SCR : generic_addr_type := 16#000F00A0#;
constant CFG_BADR_CAN : generic_addr_type := 16#000F0100#;
-- mask addr -- mask addr
constant CFG_MADR_ZERO : generic_mask_type := 0; 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_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_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_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; end package config;

View File

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

View File

@@ -19,7 +19,9 @@ entity wb_switches is
wslvo : out wb_slv_out_type; wslvo : out wb_slv_out_type;
buttons : in std_logic_vector(4 downto 0); 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; end wb_switches;
@@ -28,6 +30,8 @@ architecture Behavioral of wb_switches is
signal data : std_logic_vector(20 downto 0); signal data : std_logic_vector(20 downto 0);
signal ack : std_logic; signal ack : std_logic;
signal old_input : std_logic_vector(20 downto 0);
begin begin
process(clk) process(clk)
@@ -55,6 +59,26 @@ begin
end if; end if;
end process; 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(20 downto 0) <= data;
wslvo.dat(31 downto 21) <= (others=>'0'); wslvo.dat(31 downto 21) <= (others=>'0');

View File

@@ -111,13 +111,13 @@ begin
--setup both can nodes --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; --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; wait for 1000 ns;
--setup and execute a 2 byte transmission in controller 1 --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); tx_vector(2) <= tx_vector(1);
--manual ack by copying controler 2's ack --manual ack by copying controler 2's ack
@@ -131,7 +131,7 @@ begin
--read status register of controller 1 --read status register of controller 1
can_wb_read_reg(wbs_i1, wbs_o1, 2, clk); can_wb_read_reg(wbs_i1, wbs_o1, 2, clk);
--read from controller 2's read buffer --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; wait for 1200 ns;
--release receive buffer of controller 2 --release receive buffer of controller 2
@@ -146,8 +146,8 @@ begin
wait on irq_on2; wait on irq_on2;
--read from both receive buffers --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("/home/derek/Git/lt16lab/soc/testbench/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_data2.tdf", wbs_i2, wbs_o2, clk);
wait for 2400 ns; wait for 2400 ns;
--release both receive buffers --release both receive buffers
can_wb_write_reg(wbs_i1, wbs_o1, 1, "00000100", clk); 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 buttons: std_logic_vector(4 downto 0);
signal switches : std_logic_vector(15 downto 0); signal switches : std_logic_vector(15 downto 0);
signal interrupt : std_logic;
signal slvi : wb_slv_in_type; signal slvi : wb_slv_in_type;
signal slvo : wb_slv_out_type; signal slvo : wb_slv_out_type;
@@ -38,6 +40,7 @@ BEGIN
rst => rst, rst => rst,
buttons => buttons, buttons => buttons,
switches => switches, switches => switches,
interrupt => interrupt,
wslvi => slvi, wslvi => slvi,
wslvo => slvo wslvo => slvo
); );
@@ -75,6 +78,31 @@ BEGIN
wait for 100 ns; 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; assert false report "Simulation terminated!" severity failure;
end process stimuli; 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 entity lt16soc_top is
generic( 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( port(
-- clock signal -- clock signal
@@ -28,7 +28,10 @@ port(
sw : in std_logic_vector(15 downto 0); sw : in std_logic_vector(15 downto 0);
anodes : out std_logic_vector(7 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; end entity lt16soc_top;
@@ -40,7 +43,7 @@ architecture RTL of lt16soc_top is
signal rst_gen : std_logic; 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"; constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"1000";
signal slvo : wb_slv_out_vector := (others=> wbs_out_none); signal slvo : wb_slv_out_vector := (others=> wbs_out_none);
@@ -180,12 +183,32 @@ begin
addrmask=>CFG_MADR_DMEM) addrmask=>CFG_MADR_DMEM)
port map(clk,rst_gen,slvi(CFG_DMEM),slvo(CFG_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 leddev : wb_led
generic map( generic map(
CFG_BADR_LED,CFG_MADR_LED CFG_BADR_LED,
CFG_MADR_LED
) )
port map( 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 swdev : wb_switches
@@ -198,10 +221,15 @@ begin
timerdev : wb_timer timerdev : wb_timer
generic map( generic map(
CFG_BADR_TIMER,CFG_MADR_TIMER CFG_BADR_TIMER,
CFG_MADR_TIMER
) )
port map( 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 scrollingdev : wb_scrolling

View File

@@ -81,8 +81,8 @@ set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btn[4]
##Pmod Headers ##Pmod Headers
##Pmod Header JA ##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 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 { JA[2] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2] 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 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 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] #set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { JA[7] }]; #IO_L16N_T2_A27_15 Sch=ja[7]