From 65c3417181d66cf4de3aa1c62ee2a4401e3ef6f2 Mon Sep 17 00:00:00 2001 From: Alexander Oh Date: Tue, 25 May 2010 01:47:07 +0200 Subject: [PATCH] pc and uart compile --- src/Makefile | 2 +- src/beh_pc_communication_tb.vhd | 61 +++++++++----- src/pc_communication.vhd | 121 +++++++++++++++++++++----- src/uart_rx.vhd | 145 +++++++++++--------------------- 4 files changed, 189 insertions(+), 140 deletions(-) diff --git a/src/Makefile b/src/Makefile index 4cd647e..3200212 100644 --- a/src/Makefile +++ b/src/Makefile @@ -33,7 +33,7 @@ WORK := work # o source files der module # o reihenfolge ist wichtig # o keine testbechnes hier angeben -SRCFILES := alu parser scanner display sp_ram history uart_tx uart_rx +SRCFILES := alu parser scanner display sp_ram history uart_tx uart_rx pc_communication # o files der packages # o keine testbechnes hier angeben diff --git a/src/beh_pc_communication_tb.vhd b/src/beh_pc_communication_tb.vhd index c862095..ebb52b7 100644 --- a/src/beh_pc_communication_tb.vhd +++ b/src/beh_pc_communication_tb.vhd @@ -6,10 +6,27 @@ use work.textmode_vga_component_pkg.all; use work.textmode_vga_pkg.all; use work.textmode_vga_platform_dependent_pkg.all; +-- this is for test file io +use std.textio.all; + entity beh_pc_communication_tb is end entity beh_pc_communication_tb; architecture sim of beh_pc_communication_tb is + type byte_file_type is file of hbyte; + signal sys_clk : std_logic; + signal sys_res_n : std_logic; + signal btn_a : std_logic; + signal tx_new : std_logic; + signal tx_done : std_logic; + signal rx_new : std_logic; + signal d_get : std_logic; + signal d_done : std_logic; + signal rx_data, tx_data : std_logic_vector(7 downto 0); + + signal d_zeile : hzeile; + signal d_spalte : hspalte; + signal d_char : hbyte; begin -- display inst : entity work.pc_communication(beh) @@ -17,24 +34,24 @@ begin sys_clk => sys_clk, sys_res_n => sys_res_n, - --button=> , + --button btn_a => btn_a, - --uart_tx=> , + --uart_tx tx_data => tx_data, tx_new => tx_new, tx_done => tx_done, - --uart_rx=> , + --uart_rx rx_data => rx_data, rx_new => rx_new, - -- History=> , + -- History d_zeile => d_zeile, d_spalte => d_spalte, d_get => d_get, d_done => d_done, - d_char => d_char--, + d_char => d_char ); clk : process @@ -43,30 +60,34 @@ begin wait for 15 ns; sys_clk <= '1'; wait for 15 ns; - if stop = true then - wait; - end if; end process clk; - stub_history process (d_get) - file f : text open read_mode is "../../src/pc_communication.test"; + stub_history : process + file f : byte_file_type open read_mode is "../../src/pc_communication.test"; + variable rb : hbyte; begin - if rising_edge(d_get) then - read(f, d_char); - wait 30 ns; - done <= d_done; - end if; + wait until rising_edge(d_get); + assert not endfile(f) report "test beendet" severity failure; + read(f, rb); + wait for 30 ns; + d_char <= rb; + d_done <= '1'; + wait for 15 ns; + d_done <= '0'; end process stub_history; - process + reset_and_button : process begin -- init & reset -- we only simulate pressing of button a by now! - sys_res_n <= 0; + sys_res_n <= '0'; wait for 100 ns; - sys_res_n <= 1; + sys_res_n <= '1'; - btn_a <= 1; + btn_a <= '1'; + wait for 15ns; + btn_a <= '0'; wait; - end process; + end process reset_and_button; + end architecture sim; diff --git a/src/pc_communication.vhd b/src/pc_communication.vhd index 3681c69..5351784 100644 --- a/src/pc_communication.vhd +++ b/src/pc_communication.vhd @@ -3,7 +3,6 @@ use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.gen_pkg.all; - entity pc_communication is port ( sys_clk : in std_logic; @@ -18,51 +17,127 @@ entity pc_communication is tx_done : in std_logic; --uart_rx - rx_data : in std_logic_vector(7 downt 0); --not really required - rx_new : in std_logic_vector; + rx_data : in std_logic_vector(7 downto 0); --not really required + rx_new : in std_logic; -- History d_zeile : out hzeile; d_spalte : out hspalte; d_get : out std_logic; d_done : in std_logic; - d_char : in hbyte --; + d_char : in hbyte ); end entity pc_communication; +architecture beh of pc_communication is + signal push_history, push_history_next : std_logic; + signal spalte, spalte_next : hspalte; + signal zeile , zeile_next : hzeile; + signal spalte_up, spalte_up_next : std_logic; + + signal char, char_next : hbyte; + signal char_en : std_logic; + type STATE_PC is (IDLE, FETCH, FORWARD, DONE); + signal state, state_next : STATE_PC ; -architecture beh of display is - signal push_history, push_history_next : std_logic; begin - sync_push_history : process (sys_clk, sys_res_n) + sync: process (sys_clk, sys_res_n) begin if sys_res_n = '0' then + state <= IDLE; push_history <= '0'; + spalte <= "0000000"; + zeile <= "0000000"; elsif rising_edge(sys_clk) then push_history <= push_history_next; + spalte <= spalte_next; + zeile <= zeile_next; + state <= state_next; + if (char_en = '1') then + state <= state_next; + end if; end if; - end process sync_push_history; + end process sync; - push_history : process(rx_new, rx_data, btn_a) + process (spalte_up) + variable spalte_tmp, zeile_tmp : integer; begin - if ( (rx_new = '1' and rx_data = X"41") or btn_a '1') then - push_history_next <= '1'; + if (spalte_up = '1') then + if (spalte > X"45") then + spalte_next <= "0000000"; + zeile_tmp := to_integer(unsigned(zeile)); + zeile_tmp := zeile_tmp + 1; + zeile_next <= hbyte(to_unsigned(zeile_tmp,8)); + else + spalte_tmp := to_integer(unsigned(spalte)); + spalte_tmp := spalte_tmp + 1; + spalte_next <= hbyte(to_unsigned(spalte_tmp,8)); + zeile_next <= zeile; + end if; + spalte_up <= '0'; + end if; + end process; + + async_push_history : process (rx_new, rx_data, btn_a) + begin + if rx_new = '1' then + if rx_data = X"41" then + push_history_next <= '1'; + else + push_history_next <= '0'; + end if; + elsif btn_a = '1' then + push_history_next <= '1'; else push_history_next <= '0'; end if; - end process push_history; + end process async_push_history; + + output_pc : process (zeile, spalte) + begin + case state is + when IDLE => + spalte_next <= "0000000"; + zeile_next <= "0000000"; + when FETCH => + d_zeile <= zeile; + d_spalte <= spalte; + d_get <= '1'; + char_en <= '1'; + -- wait for timer overflow + -- increment counter + when FORWARD => + char_en <= '0'; + tx_data <= char; + tx_new <= '1'; + when DONE => + null; + -- be there for a single cycle and then + end case; + end process output_pc; + + next_state_pc : process (rx_new, btn_a) + begin + case state is + when IDLE => + if rx_new= '1' or btn_a = '1' then + state_next <= FETCH; + char <= d_char; --latch + end if; + when FETCH => + if (d_done = '1') then + state_next <= FORWARD; + end if; + when FORWARD => + if (tx_done = '1') then + state_next <= FETCH; + end if; + when DONE => + -- be there for a single cycle and then + state_next <= IDLE; + end case; + end process next_state_pc; --- sync_pc : process () --- begin --- end process sync_pc; --- --- next_state_pc : process () --- begin --- end process next_state_pc; --- --- output_pc : process () --- begin --- end process output_pc; end architecture beh; diff --git a/src/uart_rx.vhd b/src/uart_rx.vhd index e36b5c5..2f32102 100644 --- a/src/uart_rx.vhd +++ b/src/uart_rx.vhd @@ -15,22 +15,24 @@ end entity uart_rx; architecture beh of uart_rx is constant timer_max : integer := 35; + constant counter_max : integer := 9; + constant samples : integer := 8; type STATE_UART_RX is (IDLE, BUSY, DONE); signal timer, timer_next : integer range 0 to 65535; signal counter, counter_next : integer range 0 to 15; + signal sample_counter, sample_counter_next : integer range 0 to counter_max-1; signal state, state_next : STATE_UART_RX; - signal tx_data_prev : std_logic_vector(7 downto 0); -- FIXME: this isnt named next so that the interface isn't called tx_data_next ... + signal sync1, sync2, txd_next: std_logic; --synchronizers FIXME! -- these are internal signals that are actually used as in and output - signal tx_data_i : std_logic_vector(7 downto 0); + signal tx_data_prev : std_logic_vector(7 downto 0); signal tx_new_i : std_logic; + signal shift, shift_value, shift_reset : std_logic; begin ---FIXME: tx_new <= tx_new_i; - tx_data <= tx_data_i; process(sys_clk, sys_res) begin @@ -38,119 +40,70 @@ begin -- Set reset state state <= IDLE; tx_data_prev <= X"00"; + + txd_next <= '0'; --fixme: syncronizers! + sync2 <= '0'; + sync1 <= '0'; + timer <= 0; + counter <= 0; elsif rising_edge(sys_clk) then -- Store next state state <= state_next; - tx_data_prev <= tx_data_i; + if (shift = '1') then + tx_data(7 downto 1) <= tx_data_prev(6 downto 1); + tx_data(0) <= shift_value; + elsif ( shift_reset = '1') then + tx_data <= X"00"; + end if; + + txd_next <= sync2; --fixme: syncronizers! + sync2 <= sync1; + sync1 <= txd; + counter <= counter_next; + sample_counter <= sample_counter_next; + timer <= timer_next; end if; end process; process(state, txd, counter) begin state_next <= state; + + shift <= '0'; + shift_reset <='0'; + shift_value <= '0'; + timer_next <= 0; + counter_next <= 0; + case state is when IDLE => if (txd = '0') then state_next <= BUSY; - else - state_next <= IDLE; + shift_reset <= '1'; end if; when BUSY => - if (counter = 9) then --FIXME: is this true? + if (counter = counter_max) then --FIXME: is this true? state_next <= DONE; - else - state_next <= BUSY; end if; - when DONE => - state_next <= IDLE; - end case; - end process; - - process(state) - begin - -- Set default values - -- for the outputs - tx_new_i <= '0'; - - -- Calculate the outputs - -- based on the current - -- state - case state is - when IDLE => - tx_new_i <= '0'; - when BUSY => - tx_new_i <= '0'; - when DONE => - tx_new_i <= '1'; - end case; - end process; --- END FIXME: do fill this out CORRECTLY - - process (sys_clk, sys_res) - begin - if sys_res = '0' then - counter <= 0; - timer <= 0; - elsif rising_edge(sys_clk) then - counter <= counter_next; - timer <= timer_next; - end if; - end process; - - process (timer) - begin - if (timer = timer_max) then - timer_next <= 0; - else - timer_next <= timer + 1; - end if; - end process; - process (timer, counter, tx_new_i) - begin - if (tx_new_i = '1') then - if (timer = timer_max) then - if (counter > 10) then - counter_next <= 0; - else + if (timer = timer_max) then + timer_next <= 0; counter_next <= counter + 1; + if (sample_counter < samples/2) then + shift_value <= '1'; + else + shift_value <= '0'; + end if; + shift <= '1'; + else + timer_next <= timer + 1; end if; - else - counter_next <= counter; - end if; - else - counter_next <= 0; - end if; - end process; - process (counter, txd) - begin - tx_data_i <= tx_data_prev; - -- TODO: we probably want oversampling and averaging + failure! - -- FIXME: this is per se not synthesisable - case (counter) is - when 0 => --start bit - assert (txd = '0'); - when 1 => - tx_data_i(0) <= txd; - when 2 => - tx_data_i(1) <= txd; - when 3 => - tx_data_i(2) <= txd; - when 4 => - tx_data_i(3) <= txd; - when 5 => - tx_data_i(4) <= txd; - when 6 => - tx_data_i(5) <= txd; - when 7 => - tx_data_i(6) <= txd; - when 8 => - tx_data_i(7) <= txd; - when 9 => -- stop bit - assert (txd = '1'); - when others => -- idle - assert (txd = '1'); + if timer = timer_max/samples and txd_next = '1' then + sample_counter_next <= sample_counter + 1; + end if; + when DONE => + state_next <= IDLE; end case; end process; -- 2.25.1