From: Alexander Oh Date: Tue, 25 May 2010 20:24:45 +0000 (+0200) Subject: Merge branch 'master' of git@wien.tomnetworks.com:hwmod X-Git-Tag: abgabe~39 X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=hwmod.git;a=commitdiff_plain;h=20d4987577393bdd84643d9b2f73ff08c1031fe0;hp=59f12091356b946c0b8e3baa8e68e487655cfb3c Merge branch 'master' of git@wien.tomnetworks.com:hwmod --- diff --git a/quartus/project_gen.tcl b/quartus/project_gen.tcl index 242d42b..a6204ef 100644 --- a/quartus/project_gen.tcl +++ b/quartus/project_gen.tcl @@ -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 diff --git a/src/TODO b/src/TODO index 58845a9..f71752a 100644 --- 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 index 0000000..24b5e5a --- /dev/null +++ b/src/beh_loopback_tb.do @@ -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 index 0000000..a44bdbd --- /dev/null +++ b/src/beh_loopback_tb.vhd @@ -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; diff --git a/src/beh_uart_tx_tb.do b/src/beh_uart_tx_tb.do index 4f70701..014c50c 100644 --- a/src/beh_uart_tx_tb.do +++ b/src/beh_uart_tx_tb.do @@ -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 diff --git a/src/beh_uart_tx_tb.vhd b/src/beh_uart_tx_tb.vhd index 3951f9e..58fb2ab 100644 --- a/src/beh_uart_tx_tb.vhd +++ b/src/beh_uart_tx_tb.vhd @@ -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; diff --git a/src/calc.vhd b/src/calc.vhd index cdee994..bd4e903 100644 --- a/src/calc.vhd +++ b/src/calc.vhd @@ -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; diff --git a/src/uart_tx.vhd b/src/uart_tx.vhd index f3ccc8f..8f15f5b 100644 --- a/src/uart_tx.vhd +++ b/src/uart_tx.vhd @@ -1,103 +1,99 @@ 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;