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
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
\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}
# 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
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;
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,
--- /dev/null
+#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
--- /dev/null
+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;
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;
--- /dev/null
+# beachte, eingabe muss schon "scanner"-gecheckt sein
+#
+# testfall 1:
+58243
+58243
+# testfall 2:
+12345
+12345
--- /dev/null
+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;
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
(