From cabc7f314d2d8e54c5ca1b74e6af8e5e0754d94b Mon Sep 17 00:00:00 2001 From: Xiretza Date: Wed, 1 Dec 2021 13:31:07 +0100 Subject: [PATCH] 2020 day2/vhdl: update to split out runner, handle line feeds --- 2020/day2/vhdl/.gitignore | 2 +- 2020/day2/vhdl/day2.vhd | 16 ++++++++++ 2020/day2/vhdl/parser.vhd | 23 +++++++------ 2020/day2/vhdl/run.sh | 14 ++++---- 2020/day2/vhdl/sim.gtkw | 29 ++++++++--------- 2020/day2/vhdl/sim.vhd | 64 ++++++++++++++++++++++--------------- 2020/day2/vhdl/top.vhd | 33 ++++++++++--------- 2020/day2/vhdl/verifier.vhd | 6 ++-- 8 files changed, 112 insertions(+), 75 deletions(-) create mode 100644 2020/day2/vhdl/day2.vhd diff --git a/2020/day2/vhdl/.gitignore b/2020/day2/vhdl/.gitignore index 3f1310c..6d271ce 100644 --- a/2020/day2/vhdl/.gitignore +++ b/2020/day2/vhdl/.gitignore @@ -1,5 +1,5 @@ workdir/ *.o *.ghw -sim +day2 top_syn.vhd diff --git a/2020/day2/vhdl/day2.vhd b/2020/day2/vhdl/day2.vhd new file mode 100644 index 0000000..21d47df --- /dev/null +++ b/2020/day2/vhdl/day2.vhd @@ -0,0 +1,16 @@ +configuration day2 of sim is + for aoc_stdio + for dut_inst: dut + use entity work.top port map ( + clk => clk, + reset => reset, + + char => char, + input_valid => input_valid, + + num_verified => output, + output_valid => output_valid + ); + end for; + end for; +end configuration; diff --git a/2020/day2/vhdl/parser.vhd b/2020/day2/vhdl/parser.vhd index 36392f9..bb6fcde 100644 --- a/2020/day2/vhdl/parser.vhd +++ b/2020/day2/vhdl/parser.vhd @@ -5,10 +5,12 @@ entity parser is port ( clk : in std_logic; reset : in std_logic; - is_record : in std_logic; + is_data : out std_logic; + record_end : out std_logic; char : in character; + input_valid : in std_logic; num1, num2 : out natural range 0 to 99; letter : out character @@ -43,21 +45,21 @@ begin process(clk) begin if rising_edge(clk) then + record_end <= '0'; + if reset then prev_digit <= 0; state <= S_NUM1; - else + elsif input_valid then prev_digit <= 0; case state is when S_NUM1 => - if is_record then - if char = '-' then - state <= S_NUM2; - else - num1 <= complete_num; - prev_digit <= current_digit; - end if; + if char = '-' then + state <= S_NUM2; + else + num1 <= complete_num; + prev_digit <= current_digit; end if; when S_NUM2 => if char = ' ' then @@ -74,8 +76,9 @@ begin when S_END_SPACE => state <= S_DATA; when S_DATA => - if not is_record then + if char = LF then state <= S_NUM1; + record_end <= '1'; end if; end case; end if; diff --git a/2020/day2/vhdl/run.sh b/2020/day2/vhdl/run.sh index 4d5d87d..bef00f6 100755 --- a/2020/day2/vhdl/run.sh +++ b/2020/day2/vhdl/run.sh @@ -4,7 +4,8 @@ set -eu INPUT=$(readlink --canonicalize-existing "$1") MODE=${2:-} -GHDLFLAGS="--std=08 --workdir=workdir" +workdir=workdir +GHDLFLAGS="--std=08 --workdir=$workdir" cd "$(dirname "${BASH_SOURCE[0]}")" @@ -14,12 +15,13 @@ if [[ $MODE = "--synth" ]]; then for step in 1 2; do ghdl remove $GHDLFLAGS ghdl synth $GHDLFLAGS -gCOUNTER_WIDTH=12 -gSTEP="$step" parser.vhd verifier.vhd top.vhd -e top > top_syn.vhd 2>/dev/null - ghdl analyze $GHDLFLAGS top_syn.vhd sim.vhd - ghdl elab-run $GHDLFLAGS sim -gSTEP="$step" --ieee-asserts=disable < "$INPUT" + ghdl analyze $GHDLFLAGS top_syn.vhd sim.vhd day2.vhdl + ghdl elab-run $GHDLFLAGS day2 -gSTEP="$step" --wave="$workdir/synth$step.ghw" --ieee-asserts=disable < "$INPUT" done else ghdl remove $GHDLFLAGS - ghdl analyze $GHDLFLAGS parser.vhd verifier.vhd top.vhd sim.vhd - ghdl elab-run $GHDLFLAGS sim -gSTEP=1 < "$INPUT" - ghdl elab-run $GHDLFLAGS sim -gSTEP=2 < "$INPUT" + ghdl analyze $GHDLFLAGS parser.vhd verifier.vhd top.vhd sim.vhd day2.vhd + for step in 1 2; do + ghdl elab-run $GHDLFLAGS day2 -gSTEP="$step" --wave="$workdir/sim$step.ghw" < "$INPUT" + done fi diff --git a/2020/day2/vhdl/sim.gtkw b/2020/day2/vhdl/sim.gtkw index a19d999..1357f4a 100644 --- a/2020/day2/vhdl/sim.gtkw +++ b/2020/day2/vhdl/sim.gtkw @@ -1,15 +1,15 @@ [*] -[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI -[*] Wed Dec 2 10:02:23 2020 +[*] GTKWave Analyzer v3.3.109 (w)1999-2020 BSI +[*] Wed Dec 1 11:30:36 2021 [*] -[dumpfile] "/home/xiretza/dev/aoc2020/day2/sim.ghw" -[dumpfile_mtime] "Wed Dec 2 10:01:08 2020" -[dumpfile_size] 410436 -[savefile] "/home/xiretza/dev/aoc2020/day2/sim.gtkw" -[timestart] 410945000000 -[size] 1600 853 +[dumpfile] "/home/xiretza/dev/advent-of-code/2020/day2/vhdl/workdir/sim1.ghw" +[dumpfile_mtime] "Wed Dec 1 11:29:37 2021" +[dumpfile_size] 408417 +[savefile] "/home/xiretza/dev/advent-of-code/2020/day2/vhdl/sim.gtkw" +[timestart] 411833500000 +[size] 1920 1035 [pos] -1 -1 -*-27.864407 226600000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +*-25.864407 520000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] top. [treeopen] top.sim. [treeopen] top.sim.top. @@ -20,9 +20,10 @@ @28 top.sim.clk top.sim.reset -top.sim.top.parser_inst.is_record @420 top.sim.top.char +@28 +top.sim.input_valid @200 - @28 @@ -33,15 +34,13 @@ top.sim.top.num2 top.sim.top.letter @200 - -@420 -top.sim.top.verifier_inst.count +@29 +top.sim.top.record_end @28 -top.sim.top.verifier_inst.verified +top.sim.top.verified @200 - @24 #{top.sim.num_verified[11:0]} top.sim.num_verified[11] top.sim.num_verified[10] top.sim.num_verified[9] top.sim.num_verified[8] top.sim.num_verified[7] top.sim.num_verified[6] top.sim.num_verified[5] top.sim.num_verified[4] top.sim.num_verified[3] top.sim.num_verified[2] top.sim.num_verified[1] top.sim.num_verified[0] -@29 -top.sim.top.record_ended [pattern_trace] 1 [pattern_trace] 0 diff --git a/2020/day2/vhdl/sim.vhd b/2020/day2/vhdl/sim.vhd index baf7e5e..9debdb9 100644 --- a/2020/day2/vhdl/sim.vhd +++ b/2020/day2/vhdl/sim.vhd @@ -6,25 +6,44 @@ use std.textio.all; entity sim is generic ( - COUNTER_WIDTH : positive := 12; + OUTPUT_WIDTH : positive := 12; STEP : natural range 1 to 2 ); end entity; -architecture a of sim is +architecture aoc_stdio of sim is + type char_file_t is file of character; + file stdin : char_file_t open READ_MODE is "STD_INPUT"; + signal char_in : character; - signal clk, reset, is_record : std_logic; - signal num_verified : unsigned(COUNTER_WIDTH-1 downto 0); + signal clk, reset, input_valid, output_valid : std_logic; + signal output : unsigned(OUTPUT_WIDTH-1 downto 0); procedure print(s: string) is variable l : line; begin write(l, s); - writeline(output, l); + writeline(std.textio.output, l); end procedure; + + component dut is + generic ( + OUTPUT_WIDTH : positive; + STEP : natural range 1 to 2 + ); + port ( + clk : in std_logic; + reset : in std_logic; + + char : in character; + input_valid : in std_logic; + + output : out unsigned(OUTPUT_WIDTH-1 downto 0); + output_valid : out std_logic + ); + end component; begin process - variable current_line : line; variable current_char : character; variable good : boolean; @@ -38,7 +57,7 @@ begin end procedure; begin clk <= '0'; - is_record <= '0'; + input_valid <= '0'; char_in <= NUL; reset <= '1'; @@ -46,41 +65,36 @@ begin reset <= '0'; cycle_clock; - lines_loop: loop - exit lines_loop when endfile(input); - readline(input, current_line); + input_valid <= '1'; - is_record <= '1'; + chars_loop: while not endfile(stdin) loop + read(stdin, current_char); - chars_loop: loop - read(current_line, current_char, good); - exit chars_loop when not good; - - char_in <= current_char; - cycle_clock; - end loop; - - is_record <= '0'; + char_in <= current_char; cycle_clock; end loop; + input_valid <= '0'; + cycle_clock; cycle_clock; - print(to_string(to_integer(num_verified))); + assert output_valid report "Output was not valid at end of simulation" severity failure; + print(to_string(to_integer(output))); wait; end process; - top: entity work.top + dut_inst: dut generic map ( - COUNTER_WIDTH => COUNTER_WIDTH, + OUTPUT_WIDTH => OUTPUT_WIDTH, STEP => STEP ) port map ( clk => clk, reset => reset, char => char_in, - is_record => is_record, - num_verified => num_verified + input_valid => input_valid, + output => output, + output_valid => output_valid ); end architecture; diff --git a/2020/day2/vhdl/top.vhd b/2020/day2/vhdl/top.vhd index 06edc38..701cb83 100644 --- a/2020/day2/vhdl/top.vhd +++ b/2020/day2/vhdl/top.vhd @@ -4,15 +4,18 @@ use ieee.std_logic_1164.all, entity top is generic ( - COUNTER_WIDTH : positive; + OUTPUT_WIDTH : positive; STEP : natural range 1 to 2 ); port ( clk : in std_logic; reset : in std_logic; char : in character; - is_record : in std_logic; - num_verified : out unsigned(COUNTER_WIDTH-1 downto 0) + + input_valid : in std_logic; + + num_verified : out unsigned(OUTPUT_WIDTH-1 downto 0) := (others => '0'); + output_valid : out std_logic ); end entity; @@ -21,20 +24,20 @@ architecture behaviour of top is signal num1, num2 : natural range 0 to 99; signal letter : character; - signal prev_is_record : std_logic; - signal record_ended : std_logic; + signal record_end : std_logic; signal verified : std_logic; begin - record_ended <= prev_is_record and not is_record; - parser_inst: entity work.parser port map ( clk => clk, reset => reset, - is_record => is_record, + + record_end => record_end, is_data => is_data, + char => char, + input_valid => input_valid, num1 => num1, num2 => num2, @@ -45,8 +48,8 @@ begin verifier_inst: entity work.verifier(step1) port map ( clk => clk, - reset => reset or record_ended, - is_data => is_data, + reset => reset or record_end, + enable => is_data and input_valid, num1 => num1, num2 => num2, letter => letter, @@ -57,8 +60,8 @@ begin verifier_inst: entity work.verifier(step2) port map ( clk => clk, - reset => reset or record_ended, - is_data => is_data, + reset => reset or record_end, + enable => is_data and input_valid, num1 => num1, num2 => num2, letter => letter, @@ -72,13 +75,13 @@ begin process(clk) begin if rising_edge(clk) then - prev_is_record <= is_record; if reset then - prev_is_record <= '0'; num_verified <= (others => '0'); - elsif record_ended and verified then + elsif record_end and verified then num_verified <= num_verified + 1; end if; end if; end process; + + output_valid <= '1'; end architecture; diff --git a/2020/day2/vhdl/verifier.vhd b/2020/day2/vhdl/verifier.vhd index e4351d9..10588c9 100644 --- a/2020/day2/vhdl/verifier.vhd +++ b/2020/day2/vhdl/verifier.vhd @@ -5,7 +5,7 @@ entity verifier is port ( clk : in std_logic; reset : in std_logic; - is_data : in std_logic; + enable : in std_logic; num1, num2 : in natural range 0 to 99; letter : in character; @@ -24,7 +24,7 @@ begin if rising_edge(clk) then if reset then count <= 0; - elsif is_data then + elsif enable then if char = letter then count <= count + 1; end if; @@ -45,7 +45,7 @@ begin if reset then count <= 1; parity <= '0'; - elsif is_data then + elsif enable then count <= count + 1; if (count = num1 or count = num2) and char = letter then parity <= not parity;