Need Pointers on Implementing a Program Counter in VHDL (nand2tetris) - Page 1
Forum section: electronics / beginners

author: Quiggster
author_rank: Newbie
timestamp: January 02, 2023, 06:43:00 am
content: I'm currently trying to replicate the Hack CPU from nand2tetris entirely within VHDL, hopefully to run on my Basys-7 board in the future. I've run into a roadblock when implementing the course's program counter module alongside with a testbench I wrote for it. Below I’ve provided my current modules/submodules, comparison files, my testbench's waveform diagram, and the direct nand2tetris implementation and its circuit diagram to clarify.One issue that's immediately concerning is that my waveform test output shows as unassigned for the first 7 clock cycles when the comparison files and my intuition says it should report otherwise. From further cycles I can see that the functionality of the counter’s reset, load, and increment controls are fine but there seems to be a problem with values staying within the counter’s register? Following the circuit diagram, I noticed the initial tests with control signal ‘000’ (for reset, load & inc respectively) lead me to believe that there would've needed to be an initial value of zero already within the register for the testbench to work properly. I’ve tried to directly wire a logic vector equal to zero inside of the program counter’s register but that worked to no avail (the waveform diagram even ended up being the exact same!).Even if this observation isn’t a lead and or/unhelpful, I'm sure what I have needs some work so I wanted to ask for help. I also appreciate any tips on simplifying my code as well as this is also the very first time I’m learning VHDL and using "grown up" HDLs in general.Thanks everyone.My VHDL Module Files + Comparison Files:https://www.mediafire.com/file/v4f9ti9yzsewvcc/PC_Modules_Troubleshoot.rar/fileImplementation in nand2tetris HDL:https://people.duke.edu/~nts9/logicgates/PC.hdlCircuit Diagram Source:https://fkfd.me/projects/nand2tetris_1/

author: pgo
author_rank: Regular Contributor
timestamp: January 02, 2023, 09:11:33 am
content: Hi,This is a really strange way to implement a simple hardware in VHDL.A structural approach is only sensible for largish modules. It is overkill to build your hardware out of tiny pieces.Try something similar to the following:Code:library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.NUMERIC_STD.ALL;entity ProgramCounter isPort (reset : in std_logic;clock : in std_logic;clr : in std_logic;loadEn : in std_logic;countEn : in std_logic;dataIn : in std_logic_vector(15 downto 0);q : out std_logic_vector(15 downto 0));end ProgramCounter;architecture Beh of ProgramCounter issignal count : unsigned(15 downto 0);beginq <= std_logic_vector(to_unsigned(count, q'length));process (reset, clock)beginif (reset = '1') thencount <= 0;elsif rising_edge(clock) thenif (clr = '1') thencount <= 0;elsif (loadEn = '1') thencount <= dataIn;elsif (countEn = '1') thencount <= count + 1;end if;end if;end process;end Beh;Untested!

author: hli
author_rank: Frequent Contributor
timestamp: January 02, 2023, 12:03:19 pm
content: I think your issue is the 'load=true' in your register definition. Just compared this with my solution, which ORs the three signals (inc, load, reset) together and only loads the register when one of these is active, just as the definition of the PC says. I did not look at the test-bench, but I guess it will trigger this scenario in the beginning.

author: CaptDon
author_rank: Super Contributor
timestamp: January 02, 2023, 08:47:35 pm
content: Question probably best asked in the FPGA forum?

author: Quiggster
author_rank: Newbie
timestamp: January 03, 2023, 12:30:47 am
content: I messed around with your snippet and rewrote the timing intervals on my testbench to match the cycles in the expected comparison file and actually got everything to work just now so I really appreciate it! I still can't necessarily pin down what the issue with my original one was, but I'll definitely update the other things I wrote and modules in the future to be simplified with conditional statements. I think I was so caught up with the building block method approach that nand2tetris teaches that I completely ignored the other functionalities that VHDL provides to make things easier.