VHDL 4-to-1 Multiplexer: Design and Testbench

VHDL 4-to-1 Multiplexer

Entity Declaration

— Library Declaration
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

— Entity Declaration
ENTITY mux_4to1 IS
 PORT(
  x0, x1, x2, x3: IN std_logic;
  SEL   : IN std_logic_vector(1 DOWNTO 0);
  y    : OUT std_logic
 );
END ENTITY;

Architecture Declaration

— Architecture Declaration
ARCHITECTURE behavioral OF mux_4to1 IS
BEGIN
 y <= x3 WHEN sel = “11” ELSE
   x2 WHEN sel = “10” ELSE
   x1 WHEN sel = “01” ELSE
   x0;
END ARCHITECTURE;

Testbench for 4-to-1 Multiplexer

Entity Declaration

— Library Declaration
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

— Entity Declaration
ENTITY mux_4to1_tb IS
END mux_4to1_tb;

Architecture Declaration

— Architecture Declaration
ARCHITECTURE behavior OF mux_4to1_tb IS
— Component Declaration
 COMPONENT mux_4to1 IS 
  PORT (x0, x1, x2, x3: IN std_logic;
    SEL   : IN std_logic_vector(1 DOWNTO 0);
    y    : OUT std_logic);
 END COMPONENT;
 SIGNAL x0_tb, x1_tb, x2_tb, x3_tb, y_tb: std_logic;
 SIGNAL SEL_tb : std_logic_vector(1 DOWNTO 0);

BEGIN
 mux_4to1_tb : mux_4to1
 — Port map must have the same order as the component declaration
    port map (x0_tb, x1_tb, x2_tb, x3_tb, SEL_tb, y_tb);
 process begin
 x0_tb <= ‘0’;
 x1_tb <= ‘1’;
 x2_tb <= ‘0’;
 x3_tb <= ‘1’;
 SEL_tb <= “11”;
 wait for 10 ns;
 SEL_tb <= “10”;
 wait for 10 ns;
 SEL_tb <= “01”;
 wait for 10 ns;
 SEL_tb <= “00”;
 WAIT;
 END process;
END behavior;

Additional Code Snippets

Counter 0 to 9

— Library Declaration
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

— Entity Declaration
ENTITY counter_0to9 IS
PORT(
    clk, rst : IN std_logic;
    count  : OUT std_logic_vector(7 DOWNTO 0)
    );
END counter_0to9;

— Architecture Declaration
ARCHITECTURE behaviour OF counter_0to9 IS
COMPONENT clock_divider
PORT(
    clk, rst : IN std_logic;
    clk_out : OUT std_logic
    );
END COMPONENT;

COMPONENT bcd7seg
PORT(
    bcd   : IN std_logic_vector(3 DOWNTO 0);
    display : OUT std_logic_vector(7 DOWNTO 0)
    );
END COMPONENT;

SIGNAL clk_out : std_logic;
SIGNAL digit  : std_logic_vector(3 DOWNTO 0);

BEGIN
PROCESS(clk_out)
BEGIN
    IF rst = ‘0’ THEN
        digit <= “0000”;
    ELSIF rising_edge(clk_out) THEN
        IF digit = “1001” THEN
            digit <= “0000”;
        ELSE
            digit <= digit + 1;
        END IF;
    END IF;
END PROCESS;

— Drive the display through a 7-seg decoder
digit_0 : bcd7seg PORT MAP(digit, count);

— Drive the 1Hz clock
clock_1hz : clock_divider PORT MAP(clk, rst, clk_out);
END behaviour;

Clock Divider

— Library Declaration
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

— Entity Declaration
ENTITY clock_divider IS
PORT(
    clk, rst : IN std_logic;
    clk_out : OUT std_logic
    );
END clock_divider;

— Architecture Declaration
ARCHITECTURE behaviour OF clock_divider IS
SIGNAL count  : positive;
SIGNAL tmp   : std_logic := ‘0’;

BEGIN
PROCESS(clk,rst)
BEGIN
    IF rst = ‘0’ THEN
        count <= 1;
        tmp <= ‘0’;
    ELSIF rising_edge(clk) THEN
        count <= count + 1;
        — (50MHz / 1Hz) * 0.5 
        IF count = 25000000 THEN
            tmp <= NOT tmp;
            count <= 1;
        END IF;
    END IF;
    clk_out <= tmp;
END PROCESS;
END behaviour;

DE10-Lite Top Level

— Library Declaration
LIBRARY ieee;
USE ieee.std_logic_1164.all;

— Entity Declaration
ENTITY de10lite IS
PORT(
    CLOCK_50 : IN std_logic;
    KEY    : IN std_logic_vector(1 DOWNTO 0);
    SW    : IN std_logic_vector(9 DOWNTO 0); 
    HEX0   : OUT std_logic_vector(7 DOWNTO 0);
    LEDR  : OUT std_logic_vector(9 DOWNTO 0)
    );
END de10lite;

— Architecture Declaration
ARCHITECTURE behaviour OF de10lite IS
COMPONENT counter_0to9
PORT(
    clk, rst : IN std_logic;
    count  : OUT std_logic_vector(7 DOWNTO 0)
    );
END COMPONENT;

BEGIN
    counter1 : counter_0to9 PORT MAP(CLOCK_50, KEY(0), HEX0);
END behaviour;

Assembly Code Snippets

Counter

; Program to create a counter that goes from 0 to 9

.text
.org 0x000 ; start here on reset
ldm r4, r0
ldm r1, r0
ldm r2, r0
ldm r3, r0
jmp load

; Data memory layout
.data
input: bss 1
conteoMax: bss 1
result: bss 1
dispCounter: byte 0
nueve: byte 9
uno: byte 1

; Main program
.text
.org 0x010
waitIn:
ldm r4, r0
inp r4, input
jsb delay
sub r0, r3, r4
bz waitIn
ldm r4, r0
jsb delay
jsb delay 
jsb delay
jmp main
load:
ldm r2, r0
inp r2, conteoMax
jsb delay 
jsb delay
sub r0, r2, r0
bz maxerror1
jsb delay
jsb delay
jsb delay
ldm r1, dispCounter ; load values
ldm r3, uno
ldm r4, r0
jmp waitIn
main:    
ldm r4, r0
stm r1, result
out r1, result
sub r0, r2, r1
bz load
add r1, r1, 1
jmp waitIn
maxerror1: 
add r2, r2, 1
jmp load
delay:
add r7, r0, 0
again3:
add r6, r0, 0
again2:
add r5, r0, 0
again1:
add r5, r5, 1
sub r0, r5, 0xFF
bnz again1
add r6, r6, 1
sub r0, r6, 0xFF
bnz again2
add r7, r7, 1
sub r0, r7, 0x0C
bnz again3
ret

LED Control

; Read Switches and send to LEDs
 .text
 .org 0x000 ; start here on reset
 jmp main
; Data memory layout
 .data
 value_1: byte 15
 value_2: byte 20
    empty: bss 5
 result: bss 1
; Main program
  .text
  .org 0x010
main: inp r2, result ; ldm r2, value_1  
  out r2, result ; Send to output Port (LEDs)
  jmp main    ; idle loop

Value Comparison

; Program to determine greater of value_1 and value_2
; and display result in output port
.text
.org 0x000 ; start here on reset
jmp main

; Data memory layout
.data
value_1:    .byte 170
value_2:    .byte 15
result:    .res 1

; Main program
.text
.org 0x010
main:        ldm r1, value_1 ; load values
            ldm r2, value_2
            sub r0, r1, r2 ; compare values
            bc value_2_greater
            stm r1, result ; value_1 is greater
            jmp finish
value_2_greater:stm r2, result ; value_2 is greater
finish:    ldm r2, result ; Prepare to display result
        out r2, result ; Send to output Port (LEDs)
        jmp finish ; idle loop

Instruction Set

Arithmetic and Logical Instructions

  • add rd, rs, op2  Add rs and op2, result in rd
  • addc rd, rs, op2 Add rs and op2 with carry, result in rd
  • sub rd, rs, op2  Subtract op2 from rs, result in rd
  • subc rd, rs, op2 Subtract op2 from rs with carry, result in rd
  • and rd, rs, op2  Logical AND of rs and op2, result in rd
  • or rd, rs, op2  Logical OR of rs and op2, result in rd
  • xor rd, rs, op2  Logical XOR of rs and op2, result in rd
  • mask rd, rs, op2 Logical AND of rs and NOT op2, result in rd

Shift Instructions

  • shl rd, rs, count Shift rs value left count places, result in rd
  • shr rd, rs, count Shift rs value right count places, result in rd
  • rol rd, rs, count Rotate rs value left count places, result in rd
  • ror rd, rs, count Rotate rs value right count places, result in rd

Memory and I/O Instructions

  • Idm rd, (rs) + offset Load to rd from memory
  • stm rd, (rs) = offset Store to memory from rd
  • inp rd, (rs) = offset Input to rd from input controller register
  • out rd, (rs) offset Output to output controller register from rd

Branch Instructions

  • bz = disp  Branch if Z is set
  • bnz disp  Branch is Z is not set
  • bc disp  Branch if C is set
  • bnc disp  Branch if C is not set

Jump Instructions

  • jmp addr  Jump to addr
  • jsb addr  Jump to subroutine at addr

Miscellaneous Instructions

  • ret  Return from subroutine
  • reti  Return from interrupt
  • enai  Enable interrupts
  • disi  Disable interrupts
  • wait  Wait for interrupts
  • stby  Enter low-power standby mode