initial uart_rx
authorAlexander Oh <aoh@ti4.(none)>
Wed, 19 May 2010 18:52:10 +0000 (20:52 +0200)
committerAlexander Oh <aoh@ti4.(none)>
Wed, 19 May 2010 19:50:23 +0000 (21:50 +0200)
src/Makefile
src/beh_uart_rx.do [new file with mode: 0644]
src/beh_uart_rx.vhd [new file with mode: 0644]
src/uart_rx.vhd [new file with mode: 0644]

index 461f4a8142750703d9920c9deafa1497e17f3021..10f5e593cf57ad8cbfa7e29c1f8ae6840e59248c 100644 (file)
@@ -24,7 +24,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
+SRCFILES := alu parser scanner display sp_ram history uart_tx uart_rx
 
 # o files der packages
 # o keine testbechnes hier angeben
diff --git a/src/beh_uart_rx.do b/src/beh_uart_rx.do
new file mode 100644 (file)
index 0000000..4f70701
--- /dev/null
@@ -0,0 +1,56 @@
+#alias fuer simulation neustarten
+alias rr "restart -f"
+
+#signale hinzufuegen
+add wave inst/*
+
+delete wave /beh_parser_tb/inst/op1_int
+delete wave /beh_parser_tb/inst/op1
+delete wave /beh_parser_tb/inst/op1_next
+add wave -radix decimal inst/op1_int
+
+delete wave /beh_parser_tb/inst/op2_int
+delete wave /beh_parser_tb/inst/op2
+delete wave /beh_parser_tb/inst/op2_next
+add wave -radix decimal inst/op2_int
+
+delete wave /beh_parser_tb/inst/op3
+add wave -radix decimal inst/op3
+delete wave /beh_parser_tb/inst/opM
+add wave -radix decimal inst/opM
+
+delete wave /beh_parser_tb/inst/z_int
+delete wave /beh_parser_tb/inst/z_next
+add wave -radix decimal inst/z_int
+add wave -radix decimal inst/z_next
+
+delete wave /beh_parser_tb/inst/strich_int
+delete wave /beh_parser_tb/inst/strich_next
+add wave -radix decimal inst/strich_int
+add wave -radix decimal inst/strich_next
+
+delete wave /beh_parser_tb/inst/punkt_int
+delete wave /beh_parser_tb/inst/punkt_next
+add wave -radix decimal inst/punkt_int
+add wave -radix decimal inst/punkt_next
+
+delete wave /beh_parser_tb/inst/wtmp_int
+delete wave /beh_parser_tb/inst/wtmp_next
+add wave -radix decimal inst/wtmp_int
+add wave -radix decimal inst/wtmp_next
+
+delete wave /beh_parser_tb/inst/p_write_int
+delete wave /beh_parser_tb/inst/p_write_next
+delete wave /beh_parser_tb/inst/p_write
+add wave -hex inst/p_write_int
+add wave -hex inst/p_write_next
+
+
+#rauszoomen
+wave zoomout 500.0
+
+#simulation starten und 100ms lang laufen lassen (wird durch assert abgebrochen)
+run -all
+
+#ganz nach links scrollen
+wave seetime 0
diff --git a/src/beh_uart_rx.vhd b/src/beh_uart_rx.vhd
new file mode 100644 (file)
index 0000000..c3394ce
--- /dev/null
@@ -0,0 +1,57 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.gen_pkg.all;
+
+entity beh_uart_rx_tb is
+end entity beh_uart_rx_tb;
+
+architecture sim of beh_uart_rx_tb is
+
+       constant clk_period  : time := 2ns;
+       signal clock : std_logic;
+       signal reset : std_logic;
+       signal done : std_logic;
+       signal newsig : std_logic;
+       signal data : std_logic_vector(7 downto 0);
+       signal serial_out : std_logic;
+begin
+       inst : entity work.uart_tx(beh)
+       port map (
+               sys_clk => clock,
+               sys_res => reset,
+               txd => serial_out,
+               tx_data => data,
+               tx_new => newsig,
+               tx_done => done
+       );
+
+       stimuli : process
+       begin
+               newsig <= '0';
+               wait for 10ns;
+               --send 'Hallo Welt'
+               data <= X"42"; --'B'
+               newsig <= '1';
+               wait for 1000ns;
+
+               assert false report "Test finished" severity failure;
+       end process stimuli;
+
+       res_gen : process
+       begin
+               reset <= '0';
+               wait for 20ns;
+               reset <= '1';
+               wait for 1000ns;
+       end process res_gen;
+
+       clock_gen : process
+       begin
+               clock <= '0';
+               wait for clk_period/2;
+               clock <= '1';
+               wait for clk_period/2;
+       end process clock_gen;
+
+end sim;
diff --git a/src/uart_rx.vhd b/src/uart_rx.vhd
new file mode 100644 (file)
index 0000000..90dcedc
--- /dev/null
@@ -0,0 +1,157 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+--use work.gen_pkg.all;
+
+--package int_types is
+--     type STATE_UART_RX is (IDLE, BUSY, DONE);
+--end package int_types;
+
+entity uart_rx is
+port(
+       sys_clk : in std_logic;
+       sys_res : in std_logic;
+       txd : in std_logic; -- warning: this is asynchronous input!
+       tx_data : out std_logic_vector(7 downto 0); -- map this to a larger register with containing input
+       tx_new : out std_logic;
+);
+end entity uart_rx;
+
+architecture beh of uart_rx is
+       constant timer_max : integer := 35;
+
+       signal timer, timer_next : integer range 0 to 65535;
+       signal counter, counter_next : integer range 0 to 15;
+       signal state, state_next : STATE_UART_RX;
+       signal tx_data_pref : std_logic_vector(7 downto 0); -- FIXME: this isnt named next so that the interface isn't called tx_data_next ...
+
+begin
+--FIXME:
+       process(sys_clk, sys_res_n)
+               begin
+               if sys_res_n = ‘0‘ then
+                       -- Set reset state
+                       state <= IDLE;
+                       tx_data_prev <= X"0";
+               elsif rising_edge(sys_clk) then
+                       -- Store next state
+                       state <= state_next;
+                       tx_data_prev <= tx_data;
+               end if;
+       end process;
+
+       process(state, txd, counter)
+       begin
+               state_next <= state;
+               case state is
+                       when IDLE =>
+                               if (txd = 0) then
+                                       state_next <= BUSY;
+                               else
+                                       state_next <= IDLE;
+                               end if;
+                       when BUSY =>
+                               if (counter = 9) 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 <= ‘0‘;
+
+               -- Calculate the outputs
+               -- based on the current
+               -- state
+               case state is
+                       when IDLE =>
+                               tx_new <= ‘0‘;
+                       when BUSY =>
+                               tx_new <= ‘0‘;
+                               case (counter)
+                                       tx_data(counter-2) <= txd;
+                               end case;
+                       when DONE =>
+                               tx_new <= '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)
+       begin
+               if (tx_new = '1') then
+                       if (timer = timer_max) then
+                               if (counter > 10) then
+                                       counter_next <= 0;
+                               else
+                                       counter_next <= counter + 1;
+                               end if;
+                       else
+                                       counter_next <= counter;
+                       end if;
+               else
+                               counter_next <= 0;
+               end if;
+       end process;
+
+       process (counter, txd)
+       begin
+               tx_data <= 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(0) <= txd;
+                       when 2 =>
+                               tx_data(1) <= txd;
+                       when 3 =>
+                               tx_data(2) <= txd;
+                       when 4 =>
+                               tx_data(3) <= txd;
+                       when 5 =>
+                               tx_data(4) <= txd;
+                       when 6 =>
+                               tx_data(5) <= txd;
+                       when 7 =>
+                               tx_data(6) <= txd;
+                       when 8 =>
+                               tx_data(7) <= txd;
+                       when 9 => -- stop bit
+                               assert (txd = '1');
+                       when others => -- idle
+                               assert (txd = '1');
+               end case;
+       end process;
+
+       tx_done <= '0';
+
+end architecture beh;