Thank you all for your valuable feedback, I am more interested in what could be the best practical side of this course, the options I have are:
1 - Simulation-based.
2 - Use 74 series components to build circuits.
3 - Go straight to microcontrollers or maybe Arduino.
I know that practically speaking 74 series is outdated and mostly Microcontrollers, MCUs, and FPGAs are the way to go for a practical design, but what will be the best way to teach an introductory course on logic design?
FPGA might be too advanced for someone learning what a truth table is, what do you think?
Other than the constraints file, the rest of FPGA programming flows nicely from logic expressions and FSM state tables. There are just a few constructs to understand (selector, multiplexor, logic expressions and FSMs) and everything builds from there. Either of these boards would be excellent for a logic design course with an FPGA
https://digilent.com/shop/basys-3-artix-7-fpga-trainer-board-recommended-for-introductory-users/
https://digilent.com/shop/nexys-a7-fpga-trainer-board-recommended-for-ece-curriculum/ <-- my favorite
There are many other boards available at a MUCH lower cost. The thing I look for is buttons, LEDs, Displays and switches. It is quite simple to demonstrate logic expressions on an FPGA. In fact, given 16 switches and 16 LEDs, several expressions could be generated at the same time.
I suppose the student could write code for a less than optimal expression, reduce it with a Karnaugh map and add code for the optimized expression and compare the outputs on LEDs. That's still faster than wiring up a bunch of 74xx gates. And once they get to flops, the FPGA shines. By definition, FPGAs use D-flops and the student is left to figure out how to create a J-K flop. There is also a library with J-K flops. Unclocked latches are highly discouraged.
The cool thing about FPGAs is the small effort required to add a 32 bit register compared to the amount of wire-wrapping required for 7474 devices. One line of code and it exists, another few lines of code to clock it and set values. I love FPGAs!
The key topic is combinatorial logic versus sequential logic. Once the student truly understands FSMs, they are on their way to building just about anything with an FPGA. That's why I like the LC3 project, the state transition diagram is given, just code up the state actions and the CPU is just about done. Yes, there are several other components to code up but they are pretty easy.
I would hand out the constraints file and tell the students to name their HDL signals to match. Or, they can try to figure it out for themselves.
The problem with FPGAs is cost and availability. It is possible to write state machines in any computer language so there is no reason not to use the Pi Pico W with some switches and LEDs and the logic in microPython. Obviously, the C 'switch' statement is key.
Here are the first few states for LC3 and if you look in Appendix C you will see how it matches
case State is
when 0 => -- Branch Instruction
if BEN = '1' then
NextState <= 22; -- branch is taken
else
NextState <= 18; -- branch not taken
end if;
when 1 => -- ADD Instruction
if Immediate = '1' then
SR2select <= Sext5sel;
else
SR2select <= SR2outSel;
end if;
ALUop <= ALUadd;
GateBusSelect <= GateALU;
LD_Reg <= '1';
LD_CC <= '1';
NextState <= 18;
when 2 => -- LD Instruction
Addr1Select <= Addr1PC;
Addr2Select <= Addr2Sext9;
MARselect <= MARadder;
GateBusSelect <= GateMARmux;
LD_MAR <= '1';
NextState <= 25;
when 3 => -- ST Instruction
Addr1Select <= Addr1PC;
Addr2Select <= Addr2Sext9;
MARselect <= MARadder;
GateBusSelect <= GateMARmux;
LD_MAR <= '1';
NextState <= 23;
when 4 => -- JSR Instruction
if IR(11) = '1' then
NextState <= 21;
else
NextState <= 20;
end if;
How easy is that? Just follow along from the state transition diagram. Figure C-2
https://people.cs.georgetown.edu/~squier/Teaching/HardwareFundamentals/LC3-trunk/docs/LC3-uArch-PPappendC.pdf
One key point: Every signal needs to be defined in every state or latches will be generated. As a result, there are a LOT of default assignment statements in the process:
process(State, BEN, IR,MemReady, Immediate, PSR, Interrupt)
begin
-- set default values for all signals
GateBusSelect <= GatePC;
MIOenable <= '0';
LD_MAR <= '0';
...