From 78d23f1459bb2417c504823a43211f1a15eff2d1 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Tue, 17 Jan 2023 19:31:56 +0100 Subject: [PATCH] Fix scrolling controller once and for all --- soc/peripheral/scrolling_buffer.vhd | 26 +-- soc/peripheral/scrolling_controller.vhd | 106 +++++----- soc/peripheral/seven_segment_display.vhd | 4 +- soc/top/top.vhd | 18 +- soc/top/top.xdc | 16 +- soc/top/top_project.vhd | 257 +++++++++++++++++++++++ 6 files changed, 339 insertions(+), 88 deletions(-) create mode 100644 soc/top/top_project.vhd diff --git a/soc/peripheral/scrolling_buffer.vhd b/soc/peripheral/scrolling_buffer.vhd index 9e8d6be..baab2ec 100644 --- a/soc/peripheral/scrolling_buffer.vhd +++ b/soc/peripheral/scrolling_buffer.vhd @@ -65,25 +65,21 @@ begin if clk'event and clk='1' then if rst = '1' then ptr_read <= 0; - hex_char <= (others => '0'); + hex_char <= (others => '1'); else - hex_char <= (others => '0'); + if ptr_last = -1 then -- Special case + hex_char <= (others => '1'); + else + hex_char <= ring_buffer(ptr_read); + end if; if buffer_clear = '1' then ptr_read <= 0; - else - if next_char = '1' then - if ptr_last = -1 then -- Special case - hex_char <= (others => '0'); - else - hex_char <= ring_buffer(ptr_read); - - if ptr_read = ptr_last then - ptr_read <= 0; - else - ptr_read <= ptr_read + 1; - end if; - end if; + elsif next_char = '1' then + if ptr_read = ptr_last then + ptr_read <= 0; + else + ptr_read <= ptr_read + 1; end if; end if; end if; diff --git a/soc/peripheral/scrolling_controller.vhd b/soc/peripheral/scrolling_controller.vhd index 22ce7f0..48f4772 100644 --- a/soc/peripheral/scrolling_controller.vhd +++ b/soc/peripheral/scrolling_controller.vhd @@ -25,10 +25,6 @@ architecture Behavioral of scrolling_controller is type state_type is (s_off, s_wait, s_update); signal state : state_type; - signal sig_seg_shift : std_logic; - signal sig_seg_write : std_logic; - signal sig_seg_clear : std_logic; - signal current_element : integer range 0 to 16; signal current_resetted : std_logic; @@ -42,12 +38,11 @@ begin cnt_start <= '0'; next_char <= '0'; - sig_seg_shift <= '0'; - sig_seg_write <= '0'; - sig_seg_clear <= '0'; + seg_shift <= '0'; + seg_write <= '0'; + seg_clear <= '0'; current_element <= 0; - current_resetted <= '0'; else case state is when s_off => @@ -55,47 +50,52 @@ begin if on_off = '0' then state <= s_off; - sig_seg_shift <= '0'; - sig_seg_write <= '0'; - sig_seg_clear <= '0'; + seg_shift <= '0'; + seg_write <= '0'; + seg_clear <= '0'; cnt_start <= '0'; next_char <= '0'; else - state <= s_wait; - sig_seg_shift <= '0'; - sig_seg_write <= '0'; - sig_seg_clear <= '0'; + state <= s_update; + -- seg_shift <= '1'; + -- seg_write <= '1'; + -- seg_off <= hex_char(4); + -- seg_data <= hex_char(3 downto 0); + -- seg_clear <= '0'; cnt_start <= '1'; next_char <= '0'; + current_element <= current_element + 1; end if; when s_wait => if on_off = '1' then state <= s_off; - sig_seg_clear <= '1'; + seg_clear <= '1'; + seg_write <= '0'; + seg_shift <= '0'; cnt_start <= '0'; next_char <= '0'; elsif cnt_done = '0' then state <= s_wait; - sig_seg_shift <= '0'; - sig_seg_write <= '0'; - sig_seg_clear <= '0'; + seg_shift <= '0'; + seg_write <= '0'; + seg_clear <= '0'; cnt_start <= '0'; next_char <= '0'; else -- cnt_done = '1' state <= s_update; - sig_seg_shift <= '0'; - sig_seg_write <= '0'; - sig_seg_clear <= '0'; + seg_shift <= '0'; + seg_write <= '0'; + seg_clear <= '0'; cnt_start <= '1'; - if current_element < unsigned(buffer_elements) then - next_char <= '1'; - end if; + -- if current_element < unsigned(buffer_elements) then + -- next_char <= '1'; + -- else + -- next_char <= '0'; + -- end if; - current_resetted <= '0'; if current_element = 15 then - current_element <= 0; - current_resetted <= '1'; + current_element <= 1; else current_element <= current_element + 1; end if; @@ -103,14 +103,29 @@ begin when s_update => if on_off = '0' then state <= s_wait; - sig_seg_shift <= '1'; - sig_seg_write <= '1'; - sig_seg_clear <= '0'; + seg_shift <= '1'; + seg_write <= '1'; + seg_clear <= '0'; cnt_start <= '0'; - next_char <= '0'; + + if current_element <= unsigned(buffer_elements) then + next_char <= '1'; + else + next_char <= '0'; + end if; + + if current_element <= unsigned(buffer_elements) then + seg_data <= hex_char(3 downto 0); + seg_off <= hex_char(4); + else + seg_data <= x"0"; + seg_off <= '1'; + end if; else state <= s_off; - sig_seg_clear <= '1'; + seg_clear <= '1'; + seg_write <= '0'; + seg_shift <= '0'; cnt_start <= '0'; next_char <= '0'; end if; @@ -118,30 +133,5 @@ begin end if; end if; end process; - - process(clk) - begin - if clk'event and clk='1' then - if rst = '1' then - seg_data <= (others => '0'); - seg_off <= '0'; - seg_shift <= '0'; - seg_write <= '0'; - seg_clear <= '1'; - else - if current_element < unsigned(buffer_elements) and not (current_resetted = '1' and unsigned(buffer_elements) /= 16) then - seg_data <= hex_char(3 downto 0); - seg_off <= hex_char(4); - else - seg_data <= x"0"; - seg_off <= '1'; - end if; - - seg_clear <= sig_seg_clear; - seg_write <= sig_seg_write; - seg_shift <= sig_seg_shift; - end if; - end if; - end process; end Behavioral; diff --git a/soc/peripheral/seven_segment_display.vhd b/soc/peripheral/seven_segment_display.vhd index 754d01f..9b6ce67 100644 --- a/soc/peripheral/seven_segment_display.vhd +++ b/soc/peripheral/seven_segment_display.vhd @@ -54,8 +54,8 @@ begin ); timer: simple_timer - -- generic map (timer_start => x"00000008") -- for simulation - generic map (timer_start => x"00000F00") -- for board + generic map (timer_start => x"00000008") -- for simulation + -- generic map (timer_start => x"00000F00") -- for board port map( clk => clk, rst => rst, diff --git a/soc/top/top.vhd b/soc/top/top.vhd index 5f3fb09..57ae3b7 100644 --- a/soc/top/top.vhd +++ b/soc/top/top.vhd @@ -14,7 +14,7 @@ use work.lt16soc_peripherals.all; entity lt16soc_top is generic( - programfilename : string := "../../programs/interrupt_test.ram" -- see "Synthesize XST" process properties for actual value ("-generics" in .xst file)! + programfilename : string := "../../programs/project.ram" -- see "Synthesize XST" process properties for actual value ("-generics" in .xst file)! ); port( -- clock signal @@ -30,8 +30,10 @@ port( 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 + pmod_rxd : in std_logic; + pmod_txd : out std_logic; + pmod_de : out std_logic; + pmod_re_n : out std_logic ); end entity lt16soc_top; @@ -60,6 +62,8 @@ architecture RTL of lt16soc_top is signal irq_lines : std_logic_vector((2 ** irq_num_width) - 1 downto 0) := (others=>'0'); + signal can_tx : std_logic; + --////////////////////////////////////////////////////// -- components --////////////////////////////////////////////////////// @@ -193,8 +197,8 @@ begin rstn => rst_gen, wbs_i => slvi(CFG_CAN), wbs_o => slvo(CFG_CAN), - rx_i => can_rx_i, - tx_o => can_tx_o, + rx_i => pmod_rxd, + tx_o => pmod_txd, irq_on => irq_lines(4) ); @@ -246,4 +250,8 @@ begin cathodes => cathodes ); + pmod_re_n <= '0'; + pmod_de <= not can_tx; + pmod_txd <= can_tx; + end architecture RTL; diff --git a/soc/top/top.xdc b/soc/top/top.xdc index b0c57e2..8ae51cb 100644 --- a/soc/top/top.xdc +++ b/soc/top/top.xdc @@ -81,20 +81,20 @@ 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 { pmod_re_n[0] }]; #IO_L20N_T3_A19_15 Sch=ja[1] -set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { pmod_txd[0] }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2] -set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { pmod_rxd[0] }]; #IO_L21P_T3_DQS_15 Sch=ja[3] -set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { pmod_de[0] }]; #IO_L18N_T2_A23_15 Sch=ja[4] +set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { pmod_re_n }]; #IO_L20N_T3_A19_15 Sch=ja[1] +set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { pmod_txd }]; #IO_L21N_T3_DQS_A18_15 Sch=ja[2] +set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { pmod_rxd }]; #IO_L21P_T3_DQS_15 Sch=ja[3] +set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { pmod_de }]; #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 E17 IOSTANDARD LVCMOS33 } [get_ports { JA[8] }]; #IO_L16P_T2_A28_15 Sch=ja[8] #set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports { JA[9] }]; #IO_L22N_T3_A16_15 Sch=ja[9] #set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { JA[10] }]; #IO_L22P_T3_A17_15 Sch=ja[10] ##Pmod Header JB -set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { pmod_re_n[1] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1] -set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { pmod_txd[1] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2] -set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { pmod_rxd[1] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3] -set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { pmod_de[1] }]; #IO_L15P_T2_DQS_15 Sch=jb[4] +#set_property -dict { PACKAGE_PIN D14 IOSTANDARD LVCMOS33 } [get_ports { pmod_re_n[1] }]; #IO_L1P_T0_AD0P_15 Sch=jb[1] +#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports { pmod_txd[1] }]; #IO_L14N_T2_SRCC_15 Sch=jb[2] +#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { pmod_rxd[1] }]; #IO_L13N_T2_MRCC_15 Sch=jb[3] +#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { pmod_de[1] }]; #IO_L15P_T2_DQS_15 Sch=jb[4] #set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports { JB[7] }]; #IO_L11N_T1_SRCC_15 Sch=jb[7] #set_property -dict { PACKAGE_PIN F13 IOSTANDARD LVCMOS33 } [get_ports { JB[8] }]; #IO_L5P_T0_AD9P_15 Sch=jb[8] #set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { JB[9] }]; #IO_0_15 Sch=jb[9] diff --git a/soc/top/top_project.vhd b/soc/top/top_project.vhd new file mode 100644 index 0000000..82546df --- /dev/null +++ b/soc/top/top_project.vhd @@ -0,0 +1,257 @@ +-- See the file "LICENSE" for the full license governing this code. -- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use ieee.numeric_std.all; + +library work; +use work.lt16x32_internal.all; +use work.lt16x32_global.all; +use work.wishbone.all; +use work.config.all; +use work.lt16soc_memories.all; +use work.lt16soc_peripherals.all; + +entity lt16soc_top_project is +generic( + programfilename : string := "../../programs/project.ram" -- see "Synthesize XST" process properties for actual value ("-generics" in .xst file)! +); +port( + -- clock signal + clk : in std_logic; + -- external reset button + 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); + + pmod_rxd : in std_logic; + pmod_txd : out std_logic; + pmod_de : out std_logic; + pmod_re_n : out std_logic +); +end entity lt16soc_top_project; + + +architecture RTL of lt16soc_top_project is + --////////////////////////////////////////////////////// + -- constant & signal + --////////////////////////////////////////////////////// + + signal rst_gen : std_logic; + + 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); + signal msto : wb_mst_out_vector := (others=> wbm_out_none); + + signal slvi : wb_slv_in_vector := (others=> wbs_in_none); + signal msti : wb_mst_in_vector := (others=> wbm_in_none); + + signal core2mem : core_imem; + signal mem2core : imem_core; + + signal irq2core : irq_core; + signal core2irq : core_irq; + + signal irq_lines : std_logic_vector((2 ** irq_num_width) - 1 downto 0) := (others=>'0'); + + signal can_tx : std_logic; + + --////////////////////////////////////////////////////// + -- components + --////////////////////////////////////////////////////// + + component corewrapper + port( + clk : in std_logic; + rst : in std_logic; + + in_imem : in imem_core; + out_imem : out core_imem; + + in_proc : in irq_core; + out_proc : out core_irq; + + hardfault : out std_logic; + + wmsti : in wb_mst_in_type; + wmsto : out wb_mst_out_type + ); + end component; + + component irq_controller + port( + clk : in std_logic; + rst : in std_logic; + + in_proc : in core_irq; + out_proc : out irq_core; + + irq_lines : in std_logic_vector((2 ** irq_num_width) - 1 downto 0) + ); + end component; + + component wb_intercon + generic( + slv_mask_vector : std_logic_vector(0 to NWBSLV-1) := b"0000_0000_0000_0000"; + mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"0000" + ); + port( + clk : in std_logic; + rst : in std_logic; + msti : out wb_mst_in_vector; + msto : in wb_mst_out_vector; + slvi : out wb_slv_in_vector; + slvo : in wb_slv_out_vector + ); + end component; + +begin + + with RST_ACTIVE_HIGH select rst_gen <= + rst when true, + not rst when others; + + --////////////////////////////////////////////////////// + -- Instantiate + --////////////////////////////////////////////////////// + + corewrap_inst: corewrapper + port map( + clk => clk, + rst => rst_gen, + + in_imem => mem2core, + out_imem => core2mem, + + in_proc => irq2core, + out_proc => core2irq, + + hardfault => irq_lines(1), + wmsti => msti(CFG_LT16), + wmsto => msto(CFG_LT16) + + ); + + irqcontr_inst: irq_controller + port map( + clk => clk, + rst => rst_gen, + in_proc => core2irq, + out_proc => irq2core, + irq_lines => irq_lines + ); + + wbicn_inst: wb_intercon + generic map( + slv_mask_vector => slv_mask_vector, + mst_mask_vector => mst_mask_vector + ) + port map( + clk => clk, + rst => rst_gen, + msti => msti, + msto => msto, + slvi => slvi, + slvo => slvo + ); + + memwrap_inst: memwrapper + generic map( + memaddr => CFG_BADR_MEM, + addrmask => CFG_MADR_MEM, + filename => programfilename, + size => IMEMSZ + ) + port map( + clk => clk, + rst => rst_gen, + in_imem => core2mem, + out_imem => mem2core, + + fault => irq_lines(2), + wslvi => slvi(CFG_MEM), + wslvo => slvo(CFG_MEM) + ); + + dmem : wb_dmem + generic map( + memaddr=>CFG_BADR_DMEM, + addrmask=>CFG_MADR_DMEM) + port map(clk,rst_gen,slvi(CFG_DMEM),slvo(CFG_DMEM)); + + can_inst : can_vhdl_top + generic map( + memaddr=>CFG_BADR_CAN, + addrmask=>CFG_MADR_CAN + ) + port map( + clk => clk, + rstn => rst_gen, + wbs_i => slvi(CFG_CAN), + wbs_o => slvo(CFG_CAN), + rx_i => pmod_rxd, + tx_o => pmod_txd, + irq_on => irq_lines(4) + ); + + leddev : wb_led + generic map( + CFG_BADR_LED, + CFG_MADR_LED + ) + port map( + clk, + rst_gen, + led, + slvi(CFG_LED), + slvo(CFG_LED) + ); + + swdev : wb_switches + generic map( + CFG_BADR_SW,CFG_MADR_SW + ) + port map( + clk,rst_gen,slvi(CFG_SW),slvo(CFG_SW), btn, sw, irq_lines(3) + ); + + timerdev : wb_timer + generic map( + CFG_BADR_TIMER, + CFG_MADR_TIMER + ) + port map( + clk, + rst_gen, + slvi(CFG_TIMER), + slvo(CFG_TIMER) + ); + + scrollingdev : wb_scrolling + generic map( + memaddr => CFG_BADR_SCR, + addrmask => CFG_MADR_SCR + ) + port map( + clk => clk, + rst => rst_gen, + wslvi => slvi(CFG_SCR), + wslvo => slvo(CFG_SCR), + + anodes => anodes, + cathodes => cathodes + ); + + pmod_re_n <= '0'; + pmod_de <= not can_tx; + pmod_txd <= can_tx; + +end architecture RTL;