Merge branch 'master' of git@wien.tomnetworks.com:hwmod
authorAlexander Oh <oh.a@gmx.at>
Tue, 25 May 2010 20:24:45 +0000 (22:24 +0200)
committerAlexander Oh <oh.a@gmx.at>
Tue, 25 May 2010 20:24:45 +0000 (22:24 +0200)
quartus/project_gen.tcl
src/TODO
src/beh_loopback_tb.do [new file with mode: 0644]
src/beh_loopback_tb.vhd [new file with mode: 0644]
src/beh_uart_tx_tb.do
src/beh_uart_tx_tb.vhd
src/calc.vhd
src/uart_tx.vhd

index 242d42b499b014d7f3e5a7a3d38f6e5759079e9c..a6204ef19201b780ad5c2f84646529a5686cefd4 100644 (file)
@@ -49,6 +49,8 @@ if {$make_assignments} {
        set_global_assignment -name VHDL_FILE ../../src/history.vhd
        set_global_assignment -name VHDL_FILE ../../src/calc.vhd
        set_global_assignment -name VHDL_FILE ../../src/vpll.vhd
+       set_global_assignment -name VHDL_FILE ../../src/uart_tx.vhd
+       set_global_assignment -name VHDL_FILE ../../src/uart_rx.vhd
        
        #vga ip-core
        set_global_assignment -name VHDL_FILE ../../src/textmode_vga/console_sm.vhd
@@ -118,6 +120,10 @@ if {$make_assignments} {
        set_location_assignment PIN_Y26 -to ps2_clk
        set_location_assignment PIN_E21 -to ps2_data
 
+       #rs232
+       set_location_assignment PIN_D22 -to txd
+       set_location_assignment PIN_D23 -to rxd
+
        set_global_assignment -name FMAX_REQUIREMENT "33.33 MHz" -section_id sys_clk
        set_instance_assignment -name CLOCK_SETTINGS sys_clk -to sys_clk
        #warning fix fuer pll
index 58845a91bcbf85da26dfc35b06b218438784cc2f..f71752a73b4df4c12b5c35db201e1719f788713a 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -10,6 +10,9 @@
 
 - postlayout: nochmal testen obs im tilab wirklich ned geht.
 
+
+- gen_pkg: unsigned fuer hspalte, hzeile
+
 == BUGS ==
 - warum ist in beh_history s_done und finished manchmal 'X'?
 
diff --git a/src/beh_loopback_tb.do b/src/beh_loopback_tb.do
new file mode 100644 (file)
index 0000000..24b5e5a
--- /dev/null
@@ -0,0 +1,16 @@
+#alias fuer simulation neustarten
+alias rr "restart -f"
+
+#signale hinzufuegen
+add wave *
+add wave inst_rx/*
+add wave inst_tx/*
+
+#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_loopback_tb.vhd b/src/beh_loopback_tb.vhd
new file mode 100644 (file)
index 0000000..a44bdbd
--- /dev/null
@@ -0,0 +1,112 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.gen_pkg.all;
+
+entity beh_loopback_tb is
+end entity beh_loopback_tb;
+
+architecture sim of beh_loopback_tb is
+       constant CLK_FREQ : integer := 33000000;
+       constant BAUDRATE : integer := 115200;
+       constant BAUD : integer := CLK_FREQ/BAUDRATE;
+
+       signal sys_clk, sys_res_n, rxd, rx_new : std_logic;
+       signal rx_data : std_logic_vector (7 downto 0);
+       signal txd, tx_new, tx_done : std_logic;
+       signal tx_data : std_logic_vector (7 downto 0);
+       signal stop : boolean := false;
+begin
+       inst_rx : entity work.uart_rx(beh)
+       generic map (
+               CLK_FREQ => CLK_FREQ,
+               BAUDRATE => BAUDRATE
+       )
+       port map (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n,
+               rxd => rxd,
+               rx_data => rx_data,
+               rx_new => rx_new
+       );
+       inst_tx : entity work.uart_tx(beh)
+       generic map (
+               CLK_FREQ => CLK_FREQ,
+               BAUDRATE => BAUDRATE
+       )
+       port map (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n,
+               txd => txd,
+               tx_data => tx_data,
+               tx_new => tx_new,
+               tx_done => tx_done
+       );
+
+       process
+       begin
+               sys_clk <= '0';
+               wait for 15 ns;
+               sys_clk <= '1';
+               wait for 15 ns;
+               if stop = true then
+                       wait;
+               end if;
+       end process;
+
+       process
+               procedure exec_tc(testnr : integer;
+                       constant testvector : std_logic_vector(9 downto 0);
+                       constant expectedresult : std_logic_vector(7 downto 0)) is
+               begin
+                       -- vorher auf high setzen um falling edge simulieren zu koennen
+                       rxd <= '1';
+                       icwait(sys_clk, 2);
+
+                       for i in 0 to 9 loop
+                               rxd <= testvector(9-i);
+                               if i /= 9 then
+                                       icwait(sys_clk, BAUD);
+                               end if;
+                       end loop;
+               
+                       wait until rx_new = '1';
+                       if expectedresult = rx_data then
+                               report "testfall " & integer'image(testnr) & " war erfolgreich";
+                       else
+                               report "testfall " & integer'image(testnr) & " schlug fehl";
+                       end if;
+                       tx_new <= '1';
+                       tx_data <= rx_data;
+                       icwait(sys_clk, 1);
+                       wait until tx_done = '1';
+                       tx_new <= '0';
+                       wait until tx_done = '0';
+                       icwait(sys_clk, 3);
+               end;
+
+               variable testvector : std_logic_vector(9 downto 0);
+               variable expectedresult : std_logic_vector(7 downto 0);
+       begin
+               sys_res_n <= '0';
+               rxd <= '1';
+               tx_new <= '0';
+               tx_data <= (others => '0');
+               icwait(sys_clk, 10);
+               sys_res_n <= '1';
+               icwait(sys_clk, 2);
+
+               -- 1. parameter: testfallnummer
+               -- 2. parameter: STARTBIT (1 bit) - immer '0' | 8 DATENBITS | 1 STOPBIT - immer '1'
+               -- 3. parameter: byte das rauskommen soll
+               exec_tc(1, b"0000011111", b"00001111");
+               exec_tc(2, b"0101010101", b"10101010");
+               exec_tc(3, b"0110011001", b"11001100");
+               exec_tc(4, b"0001100111", b"00110011");
+               exec_tc(5, b"0010101011", b"01010101");
+               exec_tc(6, b"0100110111", b"10011011");
+
+               stop <= true;
+               wait;
+       end process;
+end sim;
index 4f70701dbb57fb6fe59cb13a9b15ca2c38690423..014c50cf1c878e1d9e8fb375b1143cbba8a7c746 100644 (file)
@@ -2,50 +2,9 @@
 alias rr "restart -f"
 
 #signale hinzufuegen
+add wave *
 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
 
index 3951f9e0efa043a585bff9243a1defcb1a4e3634..58fb2ab02d73aa9e35f4e6429775aa3ccbc019f3 100644 (file)
@@ -7,51 +7,92 @@ entity beh_uart_tx_tb is
 end entity beh_uart_tx_tb;
 
 architecture sim of beh_uart_tx_tb is
+       constant CLK_FREQ : integer := 33000000;
+       constant BAUDRATE : integer := 115200;
+       constant BAUD : integer := CLK_FREQ/BAUDRATE;
 
-       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;
+       signal sys_clk, sys_res_n, txd, tx_new, tx_done : std_logic;
+       signal tx_data : std_logic_vector (7 downto 0);
+       signal stop : boolean := false;
 begin
        inst : entity work.uart_tx(beh)
+       generic map (
+               CLK_FREQ => CLK_FREQ,
+               BAUDRATE => BAUDRATE
+       )
        port map (
-               sys_clk => clock,
-               sys_res => reset,
-               txd => serial_out,
-               tx_data => data,
-               tx_new => newsig,
-               tx_done => done
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n,
+               txd => txd,
+               tx_data => tx_data,
+               tx_new => tx_new,
+               tx_done => tx_done
        );
 
-       stimuli : process
+       process
        begin
-               newsig <= '0';
-               wait for 10ns;
-               --send 'Hallo Welt'
-               data <= X"42";
-               newsig <= '1';
-               wait for 1000ns;
+               sys_clk <= '0';
+               wait for 15 ns;
+               sys_clk <= '1';
+               wait for 15 ns;
+               if stop = true then
+                       wait;
+               end if;
+       end process;
 
-               assert false report "Test finished" severity failure;
-       end process stimuli;
+       process
+               procedure exec_tc(testnr : integer;
+                       constant expectedresult : std_logic_vector(9 downto 0);
+                       constant testvector : std_logic_vector(7 downto 0)) is
+                       variable success : boolean := true;
+               begin
+                       tx_new <= '1';
+                       tx_data <= testvector;
+                       icwait(sys_clk, 1);
 
-       res_gen : process
-       begin
-               reset <= '0';
-               wait for 20ns;
-               reset <= '1';
-               wait for 1000ns;
-       end process res_gen;
+                       -- ein BAUD-cycle auf high warten
+                       icwait(sys_clk, BAUD);
+
+                       -- in der mitte abtasten
+                       icwait(sys_clk, BAUD/2);
+                       for i in 0 to 9 loop
+                               if txd /= expectedresult(9-i) then
+                                       success := false;
+                               end if;
+                               if i /= 9 then
+                                       icwait(sys_clk, BAUD);
+                               end if;
+                       end loop;
 
-       clock_gen : process
+                       wait until tx_done = '1';
+                       tx_new <= '0';
+                       wait until tx_done = '0';
+                       if success then
+                               report "testfall " & integer'image(testnr) & " war erfolgreich";
+                       else
+                               report "testfall " & integer'image(testnr) & " schlug fehl";
+                       end if;
+                       icwait(sys_clk, 3);
+               end;
        begin
-               clock <= '0';
-               wait for clk_period/2;
-               clock <= '1';
-               wait for clk_period/2;
-       end process clock_gen;
+               sys_res_n <= '0';
+               tx_new <= '0';
+               tx_data <= (others => '0');
+               icwait(sys_clk, 10);
+               sys_res_n <= '1';
+               icwait(sys_clk, 2);
+
+               -- 1. parameter: testfallnummer
+               -- 2. parameter: STARTBIT (1 bit) - immer '0' | 8 DATENBITS | 1 STOPBIT - immer '1'
+               -- 3. parameter: byte das gesendet werden soll
+               exec_tc(1, b"0000011111", b"00001111");
+               exec_tc(2, b"0101010101", b"10101010");
+               exec_tc(3, b"0110011001", b"11001100");
+               exec_tc(4, b"0001100111", b"00110011");
+               exec_tc(5, b"0010101011", b"01010101");
+               exec_tc(6, b"0100110111", b"10011011");
 
+               stop <= true;
+               wait;
+       end process;
 end sim;
index cdee994ba039e688a034856345e279613f82c02c..bd4e903f80c51dd859479a9dd96270054c6309a0 100644 (file)
@@ -16,7 +16,8 @@ entity calc is
                -- btnA
                -- TODO: pins
                -- rs232
-               -- TODO: pins
+               rxd : in std_logic;
+               txd : out std_logic;
                -- vga
                vsync_n : out std_logic;
                hsync_n : out std_logic;
@@ -59,6 +60,12 @@ architecture top of calc is
        signal do_it, finished : std_logic;
        -- debouncing
        signal sys_res_n_sync : std_logic;
+       -- rs232
+       signal rx_new, rxd_sync : std_logic;
+       signal rx_data : std_logic_vector (7 downto 0);
+       signal tx_new, tx_done : std_logic;
+       signal tx_data : std_logic_vector (7 downto 0);
+       signal txd_out : std_logic;
 begin
        -- vga/ipcore
        textmode_vga_inst : entity work.textmode_vga(struct)
@@ -204,5 +211,47 @@ begin
                data_in => sys_res_n,
                data_out => sys_res_n_sync
        );
+
+       -- synchronizer fuer rxd
+       sync_rxd_inst : entity work.sync(beh)
+       generic map (
+               SYNC_STAGES => 2,
+               RESET_VALUE => '1'
+       )
+       port map (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n_sync,
+               data_in => rxd,
+               data_out => rxd_sync
+       );
+
+       -- rs232-rx
+       rs232rx_inst : entity work.uart_rx(beh)
+       generic map (
+               CLK_FREQ => 33330000,
+               BAUDRATE => 115200
+       )
+       port map (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n_sync,
+               rxd => rxd_sync,
+               rx_data => rx_data,
+               rx_new => rx_new
+       );
+
+       -- rs232-tx
+       rs232tx_inst : entity work.uart_tx(beh)
+       generic map (
+               CLK_FREQ => 33330000,
+               BAUDRATE => 115200
+       )
+       port map (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n,
+               txd => txd_out,
+               tx_data => tx_data,
+               tx_new => tx_new,
+               tx_done => tx_done
+       );
 end architecture top;
 
index f3ccc8f4e584bc4bdfbe0aea7793a77e7200379e..8f15f5b5d6a5b9602a10aa06ea115783a5c41016 100644 (file)
 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_TX is (IDLE, STARTBITS, PAYLOAD, PARITY, STOP, DONE);
---     type PARITY_TYPE is (ODD, EVEN, NONE);
---end package int_types;
+use work.gen_pkg.all;
 
 entity uart_tx is
-port(
-       sys_clk : in std_logic;
-       sys_res : in std_logic;
-       txd : out std_logic;
-       tx_data : in std_logic_vector(7 downto 0); -- map this to a larger register with containing input
-       tx_new : in std_logic;
-       tx_done : out std_logic
-);
+       generic (
+               CLK_FREQ : integer := 33000000;
+               BAUDRATE : integer := 115200
+       );
+       port(
+               sys_clk : in std_logic;
+               sys_res_n : in std_logic;
+               txd : out std_logic;
+               tx_data : in std_logic_vector(7 downto 0);
+               tx_new : in std_logic;
+               tx_done : out std_logic
+       );
 end entity uart_tx;
 
 architecture beh of uart_tx is
-       signal timer : integer range 0 to 65535;
-       signal timer_next : integer range 0 to 65535;
-       constant timer_max : integer := 35;
-       signal counter : integer range 0 to 15;
-       signal counter_next : integer range 0 to 15;
-       signal txd_next : std_logic;
+       constant BAUD : integer := CLK_FREQ/BAUDRATE;
+
+       type STATE_UART_TX is (IDLE, SENDBITS, DONE);
+       signal state_int, state_next : STATE_UART_TX;
+
+       signal txd_next, txd_int : std_logic;
+       signal tx_done_next, tx_done_int : std_logic;
+       signal tx_to_send : std_logic_vector(0 to 10);
+       signal bitcnt_int, bitcnt_next : integer range 0 to 11;
+       signal baudcnt_int, baudcnt_next : integer range 0 to BAUD;
 begin
-       process (sys_clk, sys_res)
+       txd <= txd_int;
+       tx_done <= tx_done_int;
+
+       process (sys_clk, sys_res_n)
        begin
-               if sys_res = '0' then
-                       counter <= 0;
-                       timer <= 0;
-                       txd <= '0';
-                       txd_next <= '0';
+               if sys_res_n = '0' then
+                       state_int <= IDLE;
+                       txd_int <= '1';
+                       tx_done_int <= '0';
+                       bitcnt_int <= 0;
+                       baudcnt_int <= 0;
+                       tx_to_send <= (others => '0');
                elsif rising_edge(sys_clk) then
-                       counter <= counter_next;
-                       timer <= timer_next;
-                       txd <= txd_next;
+                       state_int <= state_next;
+                       txd_int <= txd_next;
+                       tx_done_int <= tx_done_next;
+                       bitcnt_int <= bitcnt_next;
+                       baudcnt_int <= baudcnt_next;
+                       -- HIGHBIT (1) | STARTBIT (1) | DATA (8) | STOPBIT (1)
+                       tx_to_send <= '1' & '0' & tx_data & '1';
                end if;
        end process;
 
-       process(timer)
+       process(tx_new, tx_to_send, state_int, bitcnt_int, baudcnt_int,
+               tx_done_int, txd_int)
        begin
-               if (timer = timer_max) then
-                       timer_next <= 0;
-               else
-                       timer_next <= timer + 1;
-               end if;
-       end process;
+               state_next <= state_int;
+               tx_done_next <= tx_done_int;
+               txd_next <= txd_int;
+               bitcnt_next <= bitcnt_int;
+               baudcnt_next <= baudcnt_int;
 
-       process (timer, counter, tx_new)
-       begin
-               if (tx_new = '1') then
-                       if (timer = timer_max) then
-                               if (counter > 10) then
-                                       counter_next <= 0;
+               case state_int is
+                       when IDLE =>
+                               tx_done_next <= '0';
+                               txd_next <= '1';
+                               bitcnt_next <= 0;
+                               -- das highbyte sofort anlegen
+                               baudcnt_next <= BAUD;
+                               if tx_new = '1' then
+                                       state_next <= SENDBITS;
+                               end if;
+                       when SENDBITS =>
+                               if bitcnt_int <= 10 then
+                                       if baudcnt_int < BAUD then
+                                               baudcnt_next <= baudcnt_int + 1;
+                                       else
+                                               txd_next <= tx_to_send(bitcnt_int);
+                                               bitcnt_next <= bitcnt_int + 1;
+                                               baudcnt_next <= 0;
+                                       end if;
                                else
-                                       counter_next <= counter + 1;
+                                       -- fuer das stopbit auch noch warten
+                                       if baudcnt_int < BAUD then
+                                               baudcnt_next <= baudcnt_int + 1;
+                                       else
+                                               state_next <= DONE;
+                                       end if;
+                               end if;
+                       when DONE =>
+                               tx_done_next <= '1';
+                               if tx_new = '0' then
+                                       state_next <= IDLE;
                                end if;
-                       else
-                                       counter_next <= counter;
-                       end if;
-               else
-                               counter_next <= 0;
-               end if;
-       end process;
-
-       process (counter)
-       begin
-               -- TODO: this is always 8N1 and anything but optimal
-               case (counter) is 
-                       when 0 =>
-                               txd_next <= '1';
-                       when 1 =>
-                               txd_next <= tx_data(0);
-                       when 2 =>
-                               txd_next <= tx_data(1);
-                       when 3 =>
-                               txd_next <= tx_data(2);
-                       when 4 =>
-                               txd_next <= tx_data(3);
-                       when 5 =>
-                               txd_next <= tx_data(4);
-                       when 6 =>
-                               txd_next <= tx_data(5);
-                       when 7 =>
-                               txd_next <= tx_data(6);
-                       when 8 =>
-                               txd_next <= tx_data(7);
-                       when 9 =>
-                               txd_next <= '0';
-                       when 10 =>
-                               txd_next <= '1';
-                       when others =>
-                               txd_next <= '1';
                end case;
        end process;
-
-       tx_done <= '0';
-
 end architecture beh;