### Implement wire and reg usage examples Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/verilog/lab1.md Provides functional examples of how to use wire for continuous assignments and reg for procedural assignments in Verilog modules. ```Verilog module wire_example ( input a, output y ); wire nota; assign nota = ~a; assign y = nota; endmodule module reg_example ( input a, input b, output y ); reg tmp; always @* begin tmp = a & b; end assign y = tmp; endmodule ``` -------------------------------- ### Implement combinational logic with ports Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/verilog/lab1.md Examples showing how to define modules with input/output ports and implement logic using continuous assignments or procedural blocks. ```verilog module invert8 ( input [7:0] a, output [7:0] y ); assign y = ~a; endmodule ``` ```verilog module example_block ( input a, input [7:0] b, output y, output [7:0] z ); assign y = a; assign z = b; endmodule ``` ```verilog module example_block2 ( input a, input b, output reg y ); always @* begin y = a & b; end endmodule ``` -------------------------------- ### Verilog Equivalent of Repeat Statement Example Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/lab2.md Provides the equivalent Verilog code for the 'repeat' statement example, explicitly showing the generated parallel connections without using the 'repeat' construct. This illustrates the hardware replication performed by the 'repeat' statement. ```verilog always { out[0] = 0 out[1] = in[0] out[2] = in[1] out[3] = in[2] out[4] = in[3] out[5] = in[4] out[6] = in[5] out[7] = in[6] } ``` -------------------------------- ### Instantiate FSM Module in Alchitry Top Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/lab4.md Example of how to instantiate the simple_fsm module within an Alchitry top-level design, mapping inputs to clock and button signals. ```verilog simple_fsm simple_fsm(.clk(clk),.slow_clock(slow_clock.value),.rst(rst),.start(io_button[1])) ``` -------------------------------- ### Instantiate Registered Adder in Top Module Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/lab3.md Example of how to connect the registered adder to hardware inputs like DIP switches and buttons within an Alchitry top-level module. ```Verilog registered_rca_en rr_en(.a(io_dip[0]), .b(io_dip[1]), .clk(clk), .rst(rst),.enable(io_button[0])) always { io_led[2] = rr_en.s } ``` -------------------------------- ### Instantiate and Connect Modules Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/lab1.md Demonstrates multiple syntax patterns for instantiating modules and connecting input signals, including block-level connections and direct port mapping. ```Verilog // Block instantiation .clk(clk) { reset_conditioner reset_cond } // Regular instantiation with port setting reset_conditioner reset_cond(.clk(clk), .in(~rst_n)) // Mixed instantiation .clk(clk) { reset_conditioner reset_cond(.in(~rst_n)) } // Always block assignment always { reset_cond.clk = clk reset_cond.in = ~rst_n } ``` -------------------------------- ### Verilog FSM: START State Logic Source: https://github.com/natalieagus/50002/blob/master/docs/FPGA/Lucid V2/debugging-strategies.md This Verilog code defines the logic for the START state in a finite state machine. It checks for a start button press to transition to the INITIALIZE state. It also sets a debug signal. The example highlights a potential issue where advancing might be unlikely if multiple events occur simultaneously. ```verilog States.START: if (start_button_edge_pressed) { if (advance) game_fsm.d = States.INITIALIZE // very unlikely to happen } else { game_fsm.d = States.START } debug.d = 8d1 ``` -------------------------------- ### Assembly Function Call Example (fact) Source: https://github.com/natalieagus/50002/blob/master/docs/Software/k_stackandprocedures.md Demonstrates a basic assembly function call to 'fact(3)' using the BEQ instruction. It includes the callee entry sequence with PUSH(LP), PUSH(BP), and MOVE(SP, BP). The instruction addresses are calculated assuming a starting address of 0x0000 and each instruction being 4 bytes. ```nasm .include beta.uasm ALLOCATE(100) ADDC(R31, 3, R1) PUSH(R1) BEQ(R31, fact, LP) | call fact(3) DEALLOCATE(1) HALT() ||| callee entry procedure fact: PUSH(LP) PUSH(BP) MOVE(SP, BP) ... ``` -------------------------------- ### Configure modules using parameters Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/verilog/lab1.md Demonstrates how to define a configurable module using parameters and how to override those parameters during instantiation. ```Verilog module thing #( parameter WIDTH = 8 ) ( input [WIDTH-1:0] a, output [WIDTH-1:0] y ); assign y = a; endmodule // Instantiation with parameter override thing #(.WIDTH(16)) u1 ( .a(a16), .y(y16) ); ``` -------------------------------- ### Make Vivado Installer Executable (Linux) Source: https://github.com/natalieagus/50002/blob/master/docs/FPGA/installation.md This command is used on Linux systems to grant execute permissions to the downloaded Vivado installer file. This is a necessary step before running the installer to begin the Vivado installation process. ```shell cd ~/Downloads chmod +x FPGA[press TAB for autocompletion] ``` -------------------------------- ### Instantiating and Connecting an 8-bit Adder in Verilog Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/draft.md Demonstrates how to instantiate an N-bit adder module (where N is defined by SIZE) within the 'alchitry_top' module and connect its inputs and outputs to the IO Shield components and other FPGA outputs. This allows for testing the adder's functionality via simulation. ```verilog const SIZE = 8 // set SIZE to any number you want adder adder(#SIZE(SIZE)) adder.a = io_dip[0] adder.b = io_dip[1] adder.subtract = io_dip[2][0] io_led[0] = adder.s led[2:0] = c{adder.z, adder.v, adder.n} // signal concatenation ``` -------------------------------- ### Install UTM using Homebrew Source: https://github.com/natalieagus/50002/blob/master/docs/FPGA/fpga_applesilicon.md This command installs the UTM virtual machine application on macOS using the Homebrew package manager. Ensure Homebrew is installed and updated before running this command. ```shell brew update brew install --cask utm ``` -------------------------------- ### Install Icarus Verilog on macOS using Homebrew Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/verilog/lab1.md Installs Icarus Verilog on macOS using the Homebrew package manager. Includes verification steps. ```bash brew install icarus-verilog iverilog -V vvp -V ``` -------------------------------- ### Instantiate Modules in Verilog Source: https://github.com/natalieagus/50002/blob/master/docs/FPGA/vivado-verilog.md Demonstrates how to instantiate a button conditioner module within a top-level Verilog design, including parameter overrides. ```Verilog wire btn_raw; wire btn_clean; button_conditioner #( .CLK_FREQ(27'h5f5e100), .MIN_DELAY(5'h14), .NUM_SYNC(2'h2) ) u_bc ( .clk(clk), .in(btn_raw), .out(btn_clean) ); ``` -------------------------------- ### Install Icarus Verilog on Linux (Fedora) using dnf Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/verilog/lab1.md Installs Icarus Verilog on Fedora Linux using the dnf package manager. Includes verification steps. ```bash sudo dnf install iverilog iverilog -V vvp -V ``` -------------------------------- ### Instantiate Subcircuits in JSim Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/supplementary/supp-digital-abs.md Demonstrates how to create instances of a subcircuit definition using the X element. The syntax requires a unique instance ID, node connections, and the subcircuit name. ```JSim Xg0 d0 ctl z0 nand2 Xg1 d1 ctl z1 nand2 Xg2 d2 ctl z2 nand2 ``` -------------------------------- ### Beta Assembly Kernel Implementation Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/supplementary/supp-beta-io.md A demonstration of a minimal kernel with reset, IRQ, and ILLOP handlers. The code manages shared-memory I/O and demonstrates how to handle system exceptions in a Beta processor environment. ```Verilog const INSTRUCTIONS = { 32h6FE50000, // 0x06C JMP(R5) 32hC0BF000C, // 0x068 ADDC(R31, 12, R5) --- reset handler, go to main in user mode 32h6FE50000, // 0x064 JMP(R5) 32hC0BF000C, // 0x060 ADDC(R31, 12, R5) 32h649F000C, // 0x05C ST(R4, 0xC, R31) 32hC09F0001, // 0x058 ADDC(R31, 1, R4) 32h649F000C, // 0x054 ST(R4, 0xC, R31) 32hC09F0002, // 0x050 ADDC(R31, 2, R4) 32h649F000C, // 0x04C ST(R4, 0xC, R31) 32hC09F0003, // 0x048 ADDC(R31, 3, R4) 32h649F000C, // 0x044 ST(R4, 0xC, R31) 32hC09F0004, // 0x040 ADDC(R31, 4, R4) 32h649F000C, // 0x03C ST(R4, 0xC, R31) --- countdown 5, 4, 3, 2, 1 to be be displayed at beta_output 32hC09F0005, // 0x038 ADDC(R31, 5, R4) --- illop handler, show generic countdown 32h6FE50000, // 0x034 JMP(R5) --- execute main 32hC0BF000C, // 0x030 ADDC(R31, 12, R5) 32h649F000C, // 0x02C ST(R4, 0xC, R31) --- store to output_buffer: Mem[12] to display the input 32h609F0010, // 0x028 LD(R31, 16, R4) --- irq handler, load value from input_buffer: Mem[16] 32h00000100, // 0x024 LONG(256) --- trigger illop when R3's value is eventually 0 after several loops to main_sub 32h7BE3FFFB, // 0x020 BNE(R3, main_sub, R31) 32h607F0020, // 0x01C LD(R31, 32, R3) 32h643F0020, // 0x018 ST(R1, 32, R31) 32h90410800, // 0x014 CMPEQ(R1, R1, R2) 32hC4210001, // 0x010 SUBC(R1, 1, R1) --- main_sub 32hC03F0003, // 0x00C ADDC(R31, 3, R1) --- main 32h77FF0007, // 0x008 BR(irq) 32h77FF000C, // 0x004 BR(illop) 32h77FF0019 // 0x000 BR(reset) }; ``` ```UASM .include beta.uasm message = 0xC test_value = 32 BEQ(R31, reset, R31) BEQ(R31, illop, R31) BEQ(R31, irq, R31) main: ADDC(R31, 3, R1) main_sub: SUBC(R1, 1, R1) CMPEQ(R1, R1, R2) ST(R1, test_value) LD(R31, test_value, R3) BNE(R3, main_sub, R31) LONG(256) irq: LD(R31, 16, R4) ST(R4, message, R31) ADDC(R31, 12, R5) JMP(R5) illop: ADDC(R31, 5, R4) ST(R4, message, R31) ADDC(R31, 4, R4) ST(R4, message, R31) ADDC(R31, 3, R4) ST(R4, message, R31) ADDC(R31, 2, R4) ST(R4, message, R31) ADDC(R31, 1, R4) ST(R4, message, R31) ADDC(R31, 12, R5) JMP(R5) reset: ADDC(R31, 12, R5) JMP(R5) ``` -------------------------------- ### Install Icarus Verilog on Linux (Ubuntu/Debian) using apt Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/verilog/lab1.md Installs Icarus Verilog on Ubuntu or Debian-based Linux distributions using the apt package manager. Includes verification steps. ```bash sudo apt update sudo apt install iverilog iverilog -V vvp -V ``` -------------------------------- ### Integrate FSM in Top-Level Module Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/lab4.md Shows how to instantiate the FSM module within the top-level design and map its outputs to hardware LEDs. ```verilog simple_fsm simple_fsm(.clk(clk),.rst(rst)) always{ io_led[0] = simple_fsm.led_indicator io_led[1] = simple_fsm.index_value } ``` -------------------------------- ### Lucid V2 Blinker Module Example Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/draft.md An example of a 'blinker' module in Lucid V2. This module utilizes a 26-bit flip-flop counter to generate a blinking signal for an LED, controlled by clock and reset inputs. ```lucid module blinker ( input clk, // clock input rst, // reset output blink // output to LED ) { dff counter[26](.clk(clk), .rst(rst)) always { blink = counter.q[25] counter.d = counter.q + 1 } } ``` -------------------------------- ### VGA Screen Memory Example (Lucid V2) Source: https://github.com/natalieagus/50002/blob/master/docs/FPGA/Lucid V2/vga.md An example implementation of screen memory, which stores the character code, foreground, and background color for each text cell. This should be replaced with actual BRAM or ROM in a real design. ```lucid module vga_mem ( input clk, input reset, // Interface to vga_text_mode driver input [9:0] address, // Address for screen memory (derived from VGA counters) output reg [15:0] data_out, // 16-bit word: [FG_COLOR:10][BG_COLOR:10][CHAR_CODE:8] input [15:0] data_in, // Data to write to screen memory (if applicable) input write_enable // Write enable signal ); // Screen memory dimensions: 20 columns x 15 rows // Each cell requires: 3 bits FG color, 3 bits BG color, 8 bits char code = 14 bits // The example uses 16 bits for flexibility (e.g., 10 bits per color for higher resolution) // For 20x15 grid, total cells = 300. Address space needs to cover this. // A simple linear address mapping is assumed here. // Example: 10 bits for foreground color, 10 bits for background color, 8 bits for character code. // This example uses a simplified 16-bit data word. // [FG_COLOR: 5 bits][BG_COLOR: 5 bits][CHAR_CODE: 6 bits] -> 16 bits total // For 20x15 grid, 6 bits for char code is sufficient (64 possible chars). // In a real implementation, this would be a Block RAM (BRAM) or ROM. // For simulation purposes, a simple array can be used. // Assuming address maps directly to cell index (0 to 299 for 20x15) localparam NUM_CELLS = 20 * 15; reg [15:0] screen_buffer [0:NUM_CELLS-1]; // Initialize screen memory (optional, for simulation) always @(posedge clk or posedge reset) begin if (reset) begin for (integer i = 0; i < NUM_CELLS; i = i + 1) begin screen_buffer[i] <= 16'h0000; // Default to blank character, black background, black foreground end end end // Read operation always @(posedge clk) begin if (address < NUM_CELLS) begin data_out <= screen_buffer[address]; end else begin data_out <= 16'h0000; // Out of bounds end end // Write operation (if this module is used for writable memory) always @(posedge clk) begin if (write_enable && address < NUM_CELLS) begin screen_buffer[address] <= data_in; end end endmodule ``` -------------------------------- ### Instantiate Verilog Module 'lab1_demo' Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/verilog/lab1.md This snippet demonstrates how to instantiate a Verilog module named 'lab1_demo' and connect its ports to signals in the testbench using named port connections. This method is safer as it does not depend on the order of ports. ```verilog lab1_demo dut ( .io_button(io_button), .io_dip(io_dip), .led(led), .io_led(io_led) ); ``` -------------------------------- ### Verilog $width Function Limitation with Structs and Multi-dimensional Arrays Source: https://github.com/natalieagus/50002/blob/master/docs/FPGA/Lucid V2/lucid-v2-pitfalls.md Illustrates that the $width function cannot be used with structs or multi-dimensional arrays in Verilog. It shows examples of code that will fail when attempting to use $width in these contexts, and provides a correct usage example with an enum. ```Verilog struct color { red[8]; green[8]; blue[8]; } const COLORS = { (.red(250), .green(172), .blue(31)), (.red(20), .green(172), .blue(255)), (.red(10), .green(170), .blue(31)), (.red(0), .green(0), .blue(255)), (.red(80), .green(50), .blue(25)), (.red(90), .green(250), .blue(31)), (.red(100), .green(172), .blue(9)), (.red(28), .green(172), .blue(31)) } // This will fail: // always { // // other code // io_led[0] = $width(COLORS); // } const COLORS_2D = { { (.red(250), .green(172), .blue(31)), (.red(20), .green(172), .blue(255)), (.red(10), .green(170), .blue(31)), (.red(0), .green(0), .blue(255)) }, { (.red(80), .green(50), .blue(25)), (.red(90), .green(250), .blue(31)), (.red(100), .green(172), .blue(9)), (.red(28), .green(172), .blue(31)) } } // This will also fail: // always { // // other code // io_led[0] = $width(COLORS, 0); // } enum States { S1, S2, S3, S4, S5 } // Correct usage with enum: // always { // // other code // io_led[1] = $width(States); // will show 3, as 3 bits is the minimum bits required to encode 5 different values // } ``` -------------------------------- ### Clone JSIM starter repository Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/supplementary/supp-cmos.md This command clones the necessary starter code repository for the JSIM lab. It requires Git to be installed on the local machine. ```shell git clone https://github.com/natalieagus/jsim-kit.git ``` -------------------------------- ### Packed Word Examples for VGA Text Mode Source: https://github.com/natalieagus/50002/blob/master/docs/FPGA/Lucid V2/vga.md Demonstrates how to pack character and color information into a 16-bit word for VGA memory. The first example shows a green 'H' on a black background, and the second shows filling the screen with white 'A's on a black background. ```Verilog vga_mem_data = 16b00_010_000_01001000 // ASCII 'H' = 0x48, FG = green = 010, BG = black = 000 ``` ```Verilog vga_mem_data = 16b00_111_000_01000001 // Fill every cell with white-on-black 'A' ``` -------------------------------- ### Parameterize Verilog Module Instances Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/lab5.md Demonstrates how to apply identical parameters to an array of modules or distinct parameters to each individual instance within an array. ```verilog #PARAM_NAME(VALUE) { module_type my_module[N] } ``` ```verilog module_type my_module[10](#PARAM_NAME({8d0, 8d1, 8d2, 8d3, 8d4, 8d5, 8d6, 8d7})) ``` -------------------------------- ### Verilog Testbench Generation Prompt Example Source: https://github.com/natalieagus/50002/blob/master/docs/Labs/verilog/lab3.md An example of a detailed prompt for AI to generate a Verilog testbench for a D flip-flop. It specifies the Verilog version, design features (asynchronous reset, enable), clock parameters, input stimulus strategies, and requirements for a reference model and VCD dumping. The prompt aims to ensure comprehensive testing and clear waveform visibility. ```text Write a plain 2005 Verilog testbench for a D flip-flop with asynchronous active-high reset and enable. The testbench should run for many clock cycles and continuously exercise the design rather than using a few hand-picked cases. The clock period is 10 ns. Across the run, the input D must change at different times relative to each rising clock edge: well before the edge, just before the edge, exactly at the same simulation time as the edge, and after the edge, so the waveform clearly shows how sampling works and that changes at the edge itself are undefined. The enable signal should toggle between 0 and 1 multiple times; when enable is 1 and reset is 0, Q should follow D at rising edges, and when enable is 0 and reset is 0, Q should hold its previous value even though D continues to change. The reset signal must be asserted asynchronously at times not aligned with the clock and must override everything else: whenever reset is 1, Q must immediately go to 0 regardless of enable or D. The testbench must include a simple reference model updated on posedge clk or posedge reset that acts as an answer key for defined behavior, and the reference values should be visible in the waveform for comparison rather than used for strict pass-fail checking. The testbench should dump a VCD waveform. ```