Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

to a creation % Edit&Create; v Share abl 1s .equ LEDs, ex10000810 .text .global

ID: 3879546 • Letter: T

Question

to a creation % Edit&Create; v Share abl 1s .equ LEDs, ex10000810 .text .global _start _start: movia r2, LEDS # define LEDs 16 # base address of LEDs on DEO-Nano movi r3, ebleeeeeee # left limit set up movi r4, 0x7FFF # count to the number for delay slli r4, r4, 3 add r4, r4, r4 # the initial value set up or reset for LEDs # load the value to drive LEDs # set r6 to zero #r6++ load: movi r5, ebeeeeeee1 e loop: stw r5, e(r2) mov r6, re 2 count: addi r6, r6, 1 bne r6, r4, count beq rs, r3, load roli rs, r5,1 br loop # if(r61-r4) go to count # else if (r5-=r3) go to loop # else r5 rotate to left for 1 bit #go to 1000 453 Ph 1/27/20

Explanation / Answer

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tutorial_led_blink is
port (
    i_clock      : in std_logic;
    i_enable     : in std_logic;
    i_switch_1   : in std_logic;
    i_switch_2   : in std_logic;
    o_led_drive : out std_logic
    );
end tutorial_led_blink;

architecture rtl of tutorial_led_blink is

-- Constants to create the frequencies needed:
-- Formula is: (25 MHz / 100 Hz * 50% duty cycle)
-- So for 100 Hz: 25,000,000 / 100 * 0.5 = 125,000
constant c_CNT_100HZ : natural := 125000;
constant c_CNT_50HZ : natural := 250000;
constant c_CNT_10HZ : natural := 1250000;
constant c_CNT_1HZ   : natural := 12500000;


-- These signals will be the counters:
signal r_CNT_100HZ : natural range 0 to c_CNT_100HZ;
signal r_CNT_50HZ : natural range 0 to c_CNT_50HZ;
signal r_CNT_10HZ : natural range 0 to c_CNT_10HZ;
signal r_CNT_1HZ   : natural range 0 to c_CNT_1HZ;
  
-- These signals will toggle at the frequencies needed:
signal r_TOGGLE_100HZ : std_logic := '0';
signal r_TOGGLE_50HZ : std_logic := '0';
signal r_TOGGLE_10HZ : std_logic := '0';
signal r_TOGGLE_1HZ   : std_logic := '0';

-- One bit select wire.
signal w_LED_SELECT : std_logic;
  
begin

-- All processes toggle a specific signal at a different frequency.
-- They all run continuously even if the switches are
-- not selecting their particular output.
  
p_100_HZ : process (i_clock) is
begin
    if rising_edge(i_clock) then
      if r_CNT_100HZ = c_CNT_100HZ-1 then -- -1, since counter starts at 0
        r_TOGGLE_100HZ <= not r_TOGGLE_100HZ;
        r_CNT_100HZ    <= 0;
      else
        r_CNT_100HZ <= r_CNT_100HZ + 1;
      end if;
    end if;
end process p_100_HZ;


p_50_HZ : process (i_clock) is
begin
    if rising_edge(i_clock) then
      if r_CNT_50HZ = c_CNT_50HZ-1 then -- -1, since counter starts at 0
        r_TOGGLE_50HZ <= not r_TOGGLE_50HZ;
        r_CNT_50HZ    <= 0;
      else
        r_CNT_50HZ <= r_CNT_50HZ + 1;
      end if;
    end if;
end process p_50_HZ;

  
p_10_HZ : process (i_clock) is
begin
    if rising_edge(i_clock) then
      if r_CNT_10HZ = c_CNT_10HZ-1 then -- -1, since counter starts at 0
        r_TOGGLE_10HZ <= not r_TOGGLE_10HZ;
        r_CNT_10HZ    <= 0;
      else
        r_CNT_10HZ <= r_CNT_10HZ + 1;
      end if;
    end if;
end process p_10_HZ;

  
p_1_HZ : process (i_clock) is
begin
    if rising_edge(i_clock) then
      if r_CNT_1HZ = c_CNT_1HZ-1 then -- -1, since counter starts at 0
        r_TOGGLE_1HZ <= not r_TOGGLE_1HZ;
        r_CNT_1HZ    <= 0;
      else
        r_CNT_1HZ <= r_CNT_1HZ + 1;
      end if;
    end if;
end process p_1_HZ;

  
-- Create a multiplexor based on switch inputs
w_LED_SELECT <= r_TOGGLE_100HZ when (i_switch_1 = '0' and i_switch_2 = '0') else
                  r_TOGGLE_50HZ when (i_switch_1 = '0' and i_switch_2 = '1') else
                  r_TOGGLE_10HZ when (i_switch_1 = '1' and i_switch_2 = '0') else
                  r_TOGGLE_1HZ;

  
-- Only allow o_led_drive to drive when i_enable is high (and gate).
o_led_drive <= w_LED_SELECT and i_enable;

end rtl;


Verilog code for the design, tutorial_led_blink.v:



module tutorial_led_blink
(
   i_clock,
   i_enable,
   i_switch_1,
   i_switch_2,
   o_led_drive
   );

input i_clock;
input i_enable;
input i_switch_1;
input i_switch_2;
output o_led_drive;
   
// Constants (parameters) to create the frequencies needed:
// Input clock is 25 kHz, chosen arbitrarily.
// Formula is: (25 kHz / 100 Hz * 50% duty cycle)
// So for 100 Hz: 25,000 / 100 * 0.5 = 125
parameter c_CNT_100HZ = 125;
parameter c_CNT_50HZ = 250;
parameter c_CNT_10HZ = 1250;
parameter c_CNT_1HZ   = 12500;

// These signals will be the counters:
reg [31:0] r_CNT_100HZ = 0;
reg [31:0] r_CNT_50HZ = 0;
reg [31:0] r_CNT_10HZ = 0;
reg [31:0] r_CNT_1HZ = 0;
  
// These signals will toggle at the frequencies needed:
reg        r_TOGGLE_100HZ = 1'b0;
reg        r_TOGGLE_50HZ = 1'b0;
reg        r_TOGGLE_10HZ = 1'b0;
reg        r_TOGGLE_1HZ   = 1'b0;
  
// One bit select
reg        r_LED_SELECT;
wire       w_LED_SELECT;
  
    
begin

// All always blocks toggle a specific signal at a different frequency.
// They all run continuously even if the switches are
// not selecting their particular output.

always @ (posedge i_clock)
    begin
      if (r_CNT_100HZ == c_CNT_100HZ-1) // -1, since counter starts at 0
        begin       
          r_TOGGLE_100HZ <= !r_TOGGLE_100HZ;
          r_CNT_100HZ    <= 0;
        end
      else
        r_CNT_100HZ <= r_CNT_100HZ + 1;
    end

  
always @ (posedge i_clock)
    begin
      if (r_CNT_50HZ == c_CNT_50HZ-1) // -1, since counter starts at 0
        begin       
          r_TOGGLE_50HZ <= !r_TOGGLE_50HZ;
          r_CNT_50HZ    <= 0;
        end
      else
        r_CNT_50HZ <= r_CNT_50HZ + 1;
    end


always @ (posedge i_clock)
    begin
      if (r_CNT_10HZ == c_CNT_10HZ-1) // -1, since counter starts at 0
        begin       
          r_TOGGLE_10HZ <= !r_TOGGLE_10HZ;
          r_CNT_10HZ    <= 0;
        end
      else
        r_CNT_10HZ <= r_CNT_10HZ + 1;
    end

  
always @ (posedge i_clock)
    begin
      if (r_CNT_1HZ == c_CNT_1HZ-1) // -1, since counter starts at 0
        begin       
          r_TOGGLE_1HZ <= !r_TOGGLE_1HZ;
          r_CNT_1HZ    <= 0;
        end
      else
        r_CNT_1HZ <= r_CNT_1HZ + 1;
    end

// Create a multiplexer based on switch inputs
always @ (*)
begin
    case ({i_switch_1, i_switch_2}) // Concatenation Operator { }
      2'b11 : r_LED_SELECT <= r_TOGGLE_1HZ;
      2'b10 : r_LED_SELECT <= r_TOGGLE_10HZ;
      2'b01 : r_LED_SELECT <= r_TOGGLE_50HZ;
      2'b00 : r_LED_SELECT <= r_TOGGLE_100HZ;
    endcase    
end

assign o_led_drive = r_LED_SELECT & i_enable;

// Alternative way to design multiplexer (same as above):
// More compact, but harder to read, especially to those new to Verilog
// assign w_LED_SELECT = i_switch_1 ? (i_switch_2 ? r_TOGGLE_1HZ : r_TOGGLE_10HZ) :
                                        (i_switch_2 ? r_TOGGLE_50HZ : r_TOGGLE_100HZ);
// assign o_led_drive = w_LED_SELECT & i_enable;
    
  
end
  
endmodule