parser: erste gehversuche. im moment wird die eingabe einfach zurueckgegeben zur...
authorBernhard Urban <lewurm@gmail.com>
Sun, 9 May 2010 19:14:50 +0000 (21:14 +0200)
committerBernhard Urban <lewurm@gmail.com>
Sun, 9 May 2010 19:14:50 +0000 (21:14 +0200)
12 files changed:
quartus/project_tilab.tcl
quartus/project_web.tcl
spec/speck.tex
src/Makefile
src/alu.vhd
src/beh_alu_tb.vhd
src/beh_parser_tb.do [new file with mode: 0644]
src/beh_parser_tb.vhd [new file with mode: 0644]
src/gen_pkg.vhd
src/parser.test [new file with mode: 0644]
src/parser.vhd [new file with mode: 0644]
src/post_alu_tb.vhd

index e303aa4a1a743b5bb03dfe201e0f2f8f412e0afa..256fe6592a39452cfe427f90128c56afe585c774 100755 (executable)
@@ -32,10 +32,11 @@ if {$make_assignments} {
        set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED"
 
        #set_global_assignment -name TOP_LEVEL_ENTITY calc
-       set_global_assignment -name TOP_LEVEL_ENTITY alu
+       set_global_assignment -name TOP_LEVEL_ENTITY parser
        set_global_assignment -name VHDL_FILE ../../src/gen_pkg.vhd
        #set_global_assignment -name VHDL_FILE ../../src/calc.vhd
        set_global_assignment -name VHDL_FILE ../../src/alu.vhd
+       set_global_assignment -name VHDL_FILE ../../src/parser.vhd
 
        set_location_assignment PIN_N3 -to sys_clk
        set_location_assignment PIN_AF17 -to sys_res_n
index 5b368b7070d36e36fd4f897c7778020c816979ae..5d297b1640fc3c9dc1047cd3d12898cd3cf381e9 100755 (executable)
@@ -32,10 +32,11 @@ if {$make_assignments} {
        set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED"
 
        #set_global_assignment -name TOP_LEVEL_ENTITY calc
-       set_global_assignment -name TOP_LEVEL_ENTITY alu
+       set_global_assignment -name TOP_LEVEL_ENTITY parser
        set_global_assignment -name VHDL_FILE ../../src/gen_pkg.vhd
        #set_global_assignment -name VHDL_FILE ../../src/calc.vhd
        set_global_assignment -name VHDL_FILE ../../src/alu.vhd
+       set_global_assignment -name VHDL_FILE ../../src/parser.vhd
 
        set_location_assignment PIN_N3 -to sys_clk
        set_location_assignment PIN_AF17 -to sys_res_n
index 34cba26b3aa669a138a6f7789f97efa04896a686..dbe6ed449d58b1dbfd9b3f7edc4f219969b21039 100644 (file)
@@ -606,5 +606,16 @@ Ist das History Modul mit der Speicheranfrage fertig, wird das andere Modul \"ub
 \emph{done}-Leitung benachrichtigt. Wurde das Signal vom entsprechenden
 \emph{*\_\{get,take,do\}}-Signal quittiert kann der n\"achste Request
 verarbeitet werden.
+
+\newpage
+\section{Erg\"anzungen der Spezifikation w\"ahrend der Implementierung}
+
+\begin{itemize}
+\item Das Signal \emph{error} der ALU wurde in \emph{calc\_error} umbenannt, da
+\emph{error} ein Schl\"usselwort in VHDL ist.
+\item Die Richtungen bei den Signalen \emph{p\_read} und \emph{p\_write} wurden
+jeweils im Modul Parser und History vertauscht.
+\end{itemize}
+
 \end{document}
 
index 10cc19e7c1f15138e5248027868b0f18a2d153bb..47e4fb175b09bb80811c2ad0f3608b7842af28eb 100644 (file)
@@ -23,7 +23,7 @@ WORK := work
 # o source files der module
 # o reihenfolge ist wichtig
 # o keine testbechnes hier angeben
-SRCFILES := alu
+SRCFILES := alu parser
 
 # o files der packages
 # o keine testbechnes hier angeben
index caff4958e91f011f31ee3def3a854fe3ad9f6db9..cdb9fdd44254ecd9d5815827c877455ee6b8325c 100644 (file)
@@ -14,7 +14,7 @@ entity alu is
                op3 : out csigned;
                do_calc : in std_logic;
                calc_done : out std_logic
-               -- TODO: hier debug ports hinzufuegen ;)
+               -- TODO: calc_error : out std_logic;
        );
 end entity alu;
 
index f4f77c3073db6a070d1ff3a44b5640e55db71033..0da87c23242c55700ab63b4d0fc744b3afd72769 100644 (file)
@@ -7,26 +7,12 @@ entity beh_alu_tb is
 end entity beh_alu_tb;
 
 architecture sim of beh_alu_tb is
-       component alu is
-               port
-               (
-                       sys_clk : in std_logic;
-                       sys_res_n : in std_logic;
-                       opcode : in alu_ops;
-                       op1 : in csigned;
-                       op2 : in csigned;
-                       op3 : out csigned;
-                       do_calc : in std_logic;
-                       calc_done : out std_logic
-               );
-       end component alu;
-
        signal sys_clk, sys_res_n, do_calc, calc_done : std_logic;
        signal opcode : alu_ops;
        signal op1, op2, op3 : csigned;
        signal stop : boolean := false;
 begin
-       inst : alu
+       inst : entity work.alu(beh)
        port map
        (
                sys_clk => sys_clk,
diff --git a/src/beh_parser_tb.do b/src/beh_parser_tb.do
new file mode 100644 (file)
index 0000000..2f52a4c
--- /dev/null
@@ -0,0 +1,14 @@
+#alias fuer simulation neustarten
+alias rr "restart -f"
+
+#signale hinzufuegen
+add wave inst/*
+
+#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_parser_tb.vhd b/src/beh_parser_tb.vhd
new file mode 100644 (file)
index 0000000..fc43bcf
--- /dev/null
@@ -0,0 +1,191 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.gen_pkg.all;
+
+entity beh_parser_tb is
+end entity beh_parser_tb;
+
+architecture sim of beh_parser_tb is
+       -- system
+       signal sys_clk, sys_res_n : std_logic;
+       -- history
+       signal p_rw, p_rget, p_rdone, p_wtake, p_wdone, p_finished : std_logic;
+       signal p_read, p_write : hbyte;
+       signal p_spalte : hspalte;
+
+       -- alu
+       signal opcode : alu_ops;
+       signal op1, op2, op3 : csigned;
+       signal do_calc, calc_done : std_logic;
+
+       --scanner
+       signal do_it : std_logic;
+       signal finished : std_logic;
+
+       signal stop : boolean := false;
+begin
+       inst : entity work.parser(beh)
+       port map
+       (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n,
+               p_rw => p_rw,
+               p_spalte => p_spalte,
+               p_rget => p_rget,
+               p_rdone => p_rdone,
+               p_read => p_read,
+               p_wtake => p_wtake,
+               p_wdone => p_wdone,
+               p_write => p_write,
+               p_finished => p_finished,
+               -- ALU
+               opcode => opcode,
+               op1 => op1,
+               op2 => op2,
+               op3 => op3,
+               do_calc => do_calc,
+               calc_done => calc_done,
+               -- TODO: calc_error : in std_logic;
+               -- Scanner
+               do_it => do_it,
+               finished => finished
+       );
+
+       instalu : entity work.alu(beh)
+       port map
+       (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n,
+               do_calc => do_calc,
+               calc_done => calc_done,
+               op1 => op1,
+               op2 => op2,
+               op3 => op3,
+               opcode => opcode
+       );
+
+       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
+               -- textio stuff
+               use std.textio.all;
+               file f : text open read_mode is "../../src/parser.test";
+               variable l : line;
+
+               variable input : hstring;
+               variable expectedresult : hstring;
+               variable realresult : hstring;
+
+               variable checkall : boolean := true;
+               variable run_tc : boolean := true;
+               variable i, j, k : natural;
+       begin
+               -- init & reset
+               sys_res_n <= '0';
+               p_rdone <= '0';
+               p_wdone <= '0';
+               p_read <= (others => '0');
+               do_it <= '0';
+
+               icwait(sys_clk, 5);
+               sys_res_n <= '1';
+
+               i := 1;
+               f_loop : while not endfile(f) loop
+                       realresult := (others => character'val(0));
+
+                       f1_loop : while not endfile(f) loop
+                               readline (f, l);
+                               input := (others => character'val(0));
+                               if (l'length <= 72) then
+                                       input(1 to l'length) := l.all;
+                                       if (input(1) = '#') then
+                                               next f1_loop;
+                                       else
+                                               exit f1_loop;
+                                       end if;
+                               else
+                                       report "fehler in parser.test: eingabe zu lange in testfall " & natural'image(i);
+                                       next f_loop;
+                               end if;
+                       end loop f1_loop;
+
+                       f2_loop : while not endfile(f) loop
+                               readline (f, l);
+                               expectedresult := (others => character'val(0));
+                               if (l'length <= 72) then
+                                       expectedresult(1 to l'length) := l.all;
+                                       if (expectedresult(1) = '#') then
+                                               next f2_loop;
+                                       else
+                                               exit f2_loop;
+                                       end if;
+                               else
+                                       report "fehler in parser.test: eingabe zu lange in testfall " & natural'image(i);
+                                       next f_loop;
+                               end if;
+                       end loop f2_loop;
+
+                       report "testcase(" & natural'image(i) & ").input: " & input;
+                       report "testcase(" & natural'image(i) & ").expectedresult: " & expectedresult;
+                       i := i + 1;
+
+                       icwait(sys_clk, 5);
+                       do_it <= '1';
+                       run_tc := true;
+                       j := 1; k := 1;
+
+                       while run_tc loop
+                               wait on p_rget, p_wtake, p_finished, finished;
+                               icwait(sys_clk, 2);
+
+                               if p_rget = '1' then
+                                       p_read <= hbyte( to_unsigned(character'pos(input(j)),8) );
+                                       p_rdone <= '1';
+                                       j := j + 1;
+                               end if;
+                               if p_rget = '0' then
+                                       p_rdone <= '0';
+                               end if;
+
+                               if p_wtake = '1' then
+                                       realresult(k) := character'val(to_integer(unsigned(p_write)));
+                                       p_wdone <= '1';
+                                       k := k + 1;
+                               end if;
+                               if p_wtake = '0' then
+                                       p_wdone <= '0';
+                               end if;
+
+                               if p_finished = '1' or finished = '1' then
+                                       run_tc := false;
+                               end if;
+                       end loop;
+                       
+                       do_it <= '0';
+                       report "realresult: " & realresult;
+                       if realresult /= expectedresult then
+                               checkall := false;
+                       end if;
+                       report "==================";
+               end loop f_loop;
+
+               if checkall then
+                       report "alle testfaelle des Parser waren erfolgreich!";
+               else
+                       report "nicht alle testfaelle des Parsers waren erfolgreich!";
+               end if;
+               stop <= true;
+               wait;
+       end process;
+end architecture sim;
index 9eabeb0e177ae6b6b189119934fa8c1b3ef2eff7..e5c692e3f1ca74413eb89590fddcd87fce2e850c 100644 (file)
@@ -15,6 +15,12 @@ package gen_pkg is
        subtype csigned is signed((CBITS-1) downto 0);
        --TODO: bei CBITS-1 gibts einen overflow :/
        subtype cinteger is integer range -(2**(CBITS-2)) to ((2**(CBITS-2))-1);
+
+       subtype hspalte is std_logic_vector(6 downto 0);
+       subtype hzeile is std_logic_vector(4 downto 0);
+       subtype hbyte is std_logic_vector(7 downto 0);
+       subtype hstring is string(1 to 71);
+
        function find_msb(a : csigned) return natural;
        procedure icwait(signal clk_i : IN std_logic; cycles: Natural);
 end package gen_pkg;
diff --git a/src/parser.test b/src/parser.test
new file mode 100644 (file)
index 0000000..c3501c7
--- /dev/null
@@ -0,0 +1,8 @@
+# beachte, eingabe muss schon "scanner"-gecheckt sein
+#
+# testfall 1: 
+58243
+58243
+# testfall 2: 
+12345
+12345
diff --git a/src/parser.vhd b/src/parser.vhd
new file mode 100644 (file)
index 0000000..6e41837
--- /dev/null
@@ -0,0 +1,139 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.gen_pkg.all;
+
+entity parser is
+       port
+       (
+               sys_clk : in std_logic;
+               sys_res_n : in std_logic;
+               -- History
+               p_rw : out std_logic;
+               p_spalte : out hspalte;
+               p_rget : out std_logic;
+               p_rdone : in std_logic;
+               p_read : in hbyte;
+               p_wtake : out std_logic;
+               p_wdone : in std_logic;
+               p_write : out hbyte;
+               p_finished : out std_logic;
+               -- ALU
+               opcode : out alu_ops;
+               op1 : out csigned;
+               op2 : out csigned;
+               op3 : in csigned;
+               do_calc : out std_logic;
+               calc_done : in std_logic;
+               -- TODO: calc_error : in std_logic;
+               -- Scanner
+               do_it : in std_logic;
+               finished : out std_logic
+       );
+end entity parser;
+
+architecture beh of parser is
+       type PARSER_STATE is (SIDLE, SREAD_CHAR1, SREAD_CHAR2, SWRITE_CHAR);
+       signal state_int, state_next : PARSER_STATE;
+       signal z_int, z_next : csigned;
+       signal rbyte_int, rbyte_next : hbyte;
+       signal p_write_int, p_write_next : hbyte;
+       signal p_rget_int, p_rget_next : std_logic;
+       signal p_wtake_int, p_wtake_next : std_logic;
+       signal p_finished_int, p_finished_next : std_logic;
+begin
+       p_write <= p_write_int;
+       p_rget <= p_rget_int;
+       p_wtake <= p_wtake_int;
+       p_finished <= p_finished_int;
+
+       process(sys_clk, sys_res_n)
+       begin
+               if sys_res_n = '0' then
+                       state_int <= SIDLE;
+                       z_int <= (others => '0');
+                       rbyte_int <= (others => '0');
+                       -- out ports
+                       p_rw <= '0';
+                       p_spalte <= (others => '0');
+                       p_rget_int <= '0';
+                       p_write_int <= (others => '0');
+                       p_wtake_int <= '0';
+                       p_finished_int <= '0';
+                       opcode <= ALU_NOP;
+                       op1 <= (others => '0');
+                       op2 <= (others => '0');
+                       do_calc <= '0';
+                       finished <= '0';
+               elsif rising_edge(sys_clk) then
+                       -- internal
+                       state_int <= state_next;
+                       z_int <= z_next;
+                       rbyte_int <= rbyte_next;
+                       -- out ports
+                       p_rget_int <= p_rget_next;
+                       p_write_int <= p_write_next;
+                       p_wtake_int <= p_wtake_next;
+                       p_finished_int <= p_finished_next;
+               end if;
+       end process;
+
+       -- next state
+       process(state_int, do_it, p_rdone, p_wdone, p_read)
+       begin
+               state_next <= state_int;
+
+               case state_int is
+                       when SIDLE =>
+                               if do_it = '1' then
+                                       state_next <= SREAD_CHAR1;
+                               end if;
+                       when SREAD_CHAR1 =>
+                               if p_rdone = '1' then
+                                       state_next <= SREAD_CHAR2;
+                               end if;
+                       when SREAD_CHAR2 =>
+                               if p_wdone = '1' then
+                                       state_next <= SWRITE_CHAR;
+                               end if;
+                       when SWRITE_CHAR =>
+                               if rbyte_int = hbyte(to_unsigned(character'pos(character'val(0)), 8)) then
+                                       if do_it = '0' then
+                                               state_next <= SIDLE;
+                                       end if;
+                               else
+                                       state_next <= SREAD_CHAR1;
+                               end if;
+               end case;
+       end process;
+
+       process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int)
+       begin
+               -- internal
+               z_next <= z_int;
+               rbyte_next <= rbyte_int;
+               -- signals
+               p_rget_next <= '0';
+               p_write_next <= p_write_int;
+               p_wtake_next <= '0';
+               p_finished_next <= '0';
+
+               case state_int is
+                       when SIDLE =>
+                               z_next <= (others => '0');
+                               rbyte_next <= (others => '0');
+                               p_write_next <= (others => '0');
+                       when SREAD_CHAR1 =>
+                               p_rget_next <= '1';
+                               p_write_next <= (others => '0');
+                       when SREAD_CHAR2 =>
+                               rbyte_next <= p_read;
+                               p_wtake_next <= '1';
+                               p_write_next <= p_read;
+                       when SWRITE_CHAR =>
+                               if rbyte_int = hbyte(to_unsigned(character'pos(character'val(0)), 8)) then
+                                       p_finished_next <= '1';
+                               end if;
+               end case;
+       end process;
+end architecture beh;
index a91426aee1f32fbf92e747507155af0e696f17e5..5c05298d69e77450cf2ecdd3cfca34d7daedc2e4 100644 (file)
@@ -7,6 +7,7 @@ entity post_alu_tb is
 end entity post_alu_tb;
 
 architecture sim of post_alu_tb is
+       -- TODO: braucht man hier wirklich eine andere entity definition?
        component alu is
                port
                (