How do you displayed on HDMI screen with FPGA board? - fpga

I'm working on a project.
The goal of this project is to connect a USB-keyboard and a HDMI-display with each other using a FPGA board. That means we want to show each letter and character of the keyboard on the display when we press the key.
For the project I have chosen an Altys board build by Digilent based on FPGA Xilinx Spartan6.
For the moment I have connected the keyboard with the FPGA board and can receive data from the keyboard. It means that when I press the letter LEDs of the board light up.
I have also implemented a led sequence for each letter.
Now I try to send the letter from the keyboard to the display with HDMI output port but I have some trouble.
Does anyone have any ideas or any codes to display something with the HDMI port of FPGA board ?
Thanks for your help
The code for the keyboard connection
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
entity main is
port(
k_clk: in std_logic;
k_d: inout std_logic;
Led: out std_logic_vector(7 downto 0);
clk: in std_logic;
char: out std_logic_vector(7 downto 0)
);
end main;
architecture Behavioral of main is
signal s_k_clk: std_logic :='0';
signal ch: std_logic_vector(7 downto 0) :=(others=>'0');
signal k_clk1: std_logic;
--signal pulseInternal : std_logic;
signal makeCodeTemp : std_logic_vector(7 downto 0);
signal makeCode : std_logic_vector(7 downto 0);
signal data : std_logic_vector(21 downto 0);
signal charTemp :std_logic_vector(7 downto 0);
--signal char :std_logic_vector(7 downto 0);
begin
--------------------------------------------------------------
makeCodeTemp <= data(9 downto 2); -- Scan code window
makeCode(7) <= makeCodeTemp(0);
makeCode(6) <= makeCodeTemp(1);
makeCode(5) <= makeCodeTemp(2);
makeCode(4) <= makeCodeTemp(3);
makeCode(3) <= makeCodeTemp(4);
makeCode(2) <= makeCodeTemp(5);
makeCode(1) <= makeCodeTemp(6);
makeCode(0) <= makeCodeTemp(7);
--------------------------------------------------------------
Led(7 downto 0) <= ch(7 downto 0);
k_clk1<=k_clk xor s_k_clk;
p0:process(clk)
begin
if rising_edge(clk)then
s_k_clk<=k_clk;
end if;
end process;
p1:process(clk)
begin
if rising_edge(clk)then
if (k_clk1='1') then
data(21 downto 1) <= data(20 downto 0);
data(0) <= k_d;
--ch<=ch+1;
end if;
end if;
end process;
p2:process(clk)
begin
if rising_edge(clk) then
if data(20 downto 13) = x"0F" then char <= charTemp;
end if;
end if;
end process;
p3:process(clk)
begin
if rising_edge(clk) then
if charTemp=x"41" then
ch(0)<='1';
elsif charTemp=x"42" then
ch(1)<='1';
elsif charTemp=x"43" then
ch(2)<='1';
elsif charTemp=x"44" then
ch(3)<='1';
elsif charTemp=x"45" then
ch(4)<='1';
end if;
end if;
end process;
charTemp <= x"41" when makeCode = x"1C" else --A
x"42" when makeCode = x"32" else --B
x"43" when makeCode = x"21" else --C
x"44" when makeCode = x"23" else --D
x"45" when makeCode = x"24" else --E
x"46" when makeCode = x"2B" else --F
x"47" when makeCode = x"34" else --G
x"48" when makeCode = x"33" else --H
x"49" when makeCode = x"43" else --I
x"4A" when makeCode = x"3B" else --J
x"4B" when makeCode = x"42" else --K
x"4C" when makeCode = x"4B" else --L
x"4D" when makeCode = x"3A" else --M
x"4E" when makeCode = x"31" else --N
x"4F" when makeCode = x"44" else --O
x"50" when makeCode = x"4D" else --P
x"51" when makeCode = x"15" else --Q
x"52" when makeCode = x"2D" else --R
x"53" when makeCode = x"1B" else --S
x"54" when makeCode = x"2C" else --T
x"55" when makeCode = x"3C" else --U
x"56" when makeCode = x"2A" else --V
x"57" when makeCode = x"1D" else --W
x"58" when makeCode = x"22" else --X
x"59" when makeCode = x"35" else --Y
x"5A" when makeCode = x"1A" else --Z
x"30" when makeCode = x"45" else --0
x"31" when makeCode = x"16" else --1
x"32" when makeCode = x"1E" else --2
x"33" when makeCode = x"26" else --3
x"34" when makeCode = x"25" else --4
x"35" when makeCode = x"2E" else --5
x"36" when makeCode = x"36" else --6
x"37" when makeCode = x"3D" else --7
x"38" when makeCode = x"3E" else --8
x"39" when makeCode = x"46" else --9
x"2F" when makeCode = x"5A" else --ENTER
x"5C" when makeCode = x"66" else --Backspace
x"00"; --Null
end Behavioral;
**The code for HDMI display: **
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Library UNISIM;
use UNISIM.vcomponents.all;
entity dvid is
Port ( clk_tmds0 : in STD_LOGIC;
clk_tmds90 : in STD_LOGIC;
clk_pixel : in STD_LOGIC;
red_p : in STD_LOGIC_VECTOR (7 downto 0);
green_p : in STD_LOGIC_VECTOR (7 downto 0);
blue_p : in STD_LOGIC_VECTOR (7 downto 0);
blank : in STD_LOGIC;
hsync : in STD_LOGIC;
vsync : in STD_LOGIC;
red_s : out STD_LOGIC;
green_s : out STD_LOGIC;
blue_s : out STD_LOGIC;
clock_s : out STD_LOGIC);
end dvid;
architecture Behavioral of dvid is
COMPONENT TDMS_encoder
PORT(
clk : IN std_logic;
data : IN std_logic_vector(7 downto 0);
c : IN std_logic_vector(1 downto 0);
blank : IN std_logic;
encoded : OUT std_logic_vector(9 downto 0)
);
END COMPONENT;
COMPONENT qdr
PORT(
clk0 : IN std_logic;
clk90 : IN std_logic;
data : IN std_logic_vector(3 downto 0);
qdr : OUT std_logic
);
END COMPONENT;
signal encoded_r, encoded_g, encoded_b : std_logic_vector(9 downto 0);
-- for the control frames (blanking)
constant c_red : std_logic_vector(1 downto 0) := (others => '0');
constant c_green : std_logic_vector(1 downto 0) := (others => '0');
signal c_blue : std_logic_vector(1 downto 0);
signal latched_r : std_logic_vector(9 downto 0) := (others => '0');
signal latched_g : std_logic_vector(9 downto 0) := (others => '0');
signal latched_b : std_logic_vector(9 downto 0) := (others => '0');
signal buffer_r : std_logic_vector(9 downto 0) := (others => '0');
signal buffer_g : std_logic_vector(9 downto 0) := (others => '0');
signal buffer_b : std_logic_vector(9 downto 0) := (others => '0');
-- one hot encoded. Initial Value is important to sync with pixel chantges!
signal state : std_logic_vector(4 downto 0) := "10000";
signal bits_r : std_logic_vector(3 downto 0) := (others => '0');
signal bits_g : std_logic_vector(3 downto 0) := (others => '0');
signal bits_b : std_logic_vector(3 downto 0) := (others => '0');
signal bits_c : std_logic_vector(3 downto 0) := (others => '0');
-- output shift registers
signal sr_r : std_logic_vector(11 downto 0):= (others => '0');
signal sr_g : std_logic_vector(11 downto 0):= (others => '0');
signal sr_b : std_logic_vector(11 downto 0):= (others => '0');
signal sr_c : std_logic_vector(9 downto 0) := "0111110000";
-- Gives a startup delay to allow the fifo to fill
signal delay_ctr : std_logic_vector(3 downto 0) := (others => '0');
begin
c_blue <= vsync & hsync;
TDMS_encoder_red: TDMS_encoder PORT MAP(clk => clk_pixel, data => red_p, c => c_red, blank => blank, encoded => encoded_r);
TDMS_encoder_green: TDMS_encoder PORT MAP(clk => clk_pixel, data => green_p, c => c_green, blank => blank, encoded => encoded_g);
TDMS_encoder_blue: TDMS_encoder PORT MAP(clk => clk_pixel, data => blue_p, c => c_blue, blank => blank, encoded => encoded_b);
qdr_r: qdr PORT MAP(clk0 => clk_tmds0, clk90 => clk_tmds90, data => bits_r(3 downto 0), qdr => red_s);
qdr_g: qdr PORT MAP(clk0 => clk_tmds0, clk90 => clk_tmds90, data => bits_g(3 downto 0), qdr => green_s);
qdr_b: qdr PORT MAP(clk0 => clk_tmds0, clk90 => clk_tmds90, data => bits_b(3 downto 0), qdr => blue_s);
qdr_c: qdr PORT MAP(clk0 => clk_tmds0, clk90 => clk_tmds90, data => bits_c(3 downto 0), qdr => clock_s);
process(clk_pixel)
begin
-- Just sample the encoded pixel data, to give a smooth transition to high speed domain
if rising_edge(clk_pixel) then
buffer_r <= encoded_r;
buffer_g <= encoded_g;
buffer_b <= encoded_b;
end if;
end process;
process(clk_tmds0)
begin
if rising_edge(clk_tmds0) then
bits_r <= sr_r(3 downto 0);
bits_g <= sr_g(3 downto 0);
bits_b <= sr_b(3 downto 0);
bits_c <= sr_c(3 downto 0);
case state is
when "00001" =>
sr_r <= "00" & latched_r;
sr_g <= "00" & latched_g;
sr_b <= "00" & latched_b;
when "00010" =>
sr_r <= "0000" & sr_r(sr_r'high downto 4);
sr_g <= "0000" & sr_g(sr_g'high downto 4);
sr_b <= "0000" & sr_b(sr_b'high downto 4);
when "00100" =>
sr_r <= latched_r & sr_r(5 downto 4);
sr_g <= latched_g & sr_g(5 downto 4);
sr_b <= latched_b & sr_b(5 downto 4);
when "01000" =>
sr_r <= "0000" & sr_r(sr_r'high downto 4);
sr_g <= "0000" & sr_g(sr_g'high downto 4);
sr_b <= "0000" & sr_b(sr_b'high downto 4);
when others =>
sr_r <= "0000" & sr_r(sr_r'high downto 4);
sr_g <= "0000" & sr_g(sr_g'high downto 4);
sr_b <= "0000" & sr_b(sr_b'high downto 4);
end case;
-- Move on to the next state
state <= state(state'high-1 downto 0) & state(state'high);
-- Move the TMDS clock signal shift register
sr_c <= sr_c(3 downto 0) & sr_c(sr_c'high downto 4);
if delay_ctr(delay_ctr'high) = '0' then
delay_ctr <= delay_ctr +1;
end if;
-- Move the encoded pixel data into the fast clock domain
latched_r <= buffer_r;
latched_g <= buffer_g;
latched_b <= buffer_b;
end if;
end process;
end Behavioral;

Take a look at this user guide which covers implementing HDMI on the atlys board as a reference design.
https://www.xilinx.com/support/documentation/application_notes/xapp495_S6TMDS_Video_Interface.pdf

Related

VHDL: Cache memory output signal not consistent and varies between either halfs of the output being right, but never the whole thing

I hope you guys are well :)
I am trying to implement a simple cache memory system, however I am finding myself unable to properly do so. When I attempt to test my read miss/ read hit, I am getting the following result: VHDL Signals.
As I understand my design, the Read Miss state should be writing 1011111110101100 however I am either getting 10111111100000000 or 00000010101100. My result seems to fluctuate between both results. s_addr refers to a new instruction from the CPU which starts one process, which in turn starts the state process should there be any changes. I have provided some code. I am unsure of how to proceed. I've walked through my code and I do not understand why it splits the values like that when the output was supposed occur in one go.
Finally, I suspect that this may have something to do with the fact that my signals are initially undefined for some reason.
Full signal diagram
I am not sure why for the first 6ns, the output of s_readdatta is undefined. My tag values stored in test1 and test2 are also undefined and I am not sure why. I would appreciate any insight you guys can offer. Thank you!
VHDL code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_bit_unsigned.all;
entity cache is
generic(
ram_size : INTEGER := 32768
);
port(
clock : in std_logic;
reset : in std_logic;
-- Avalon interface --
s_addr : in std_logic_vector (31 downto 0);
s_read : in std_logic;
s_readdata : out std_logic_vector (31 downto 0);
s_write : in std_logic;
s_writedata : in std_logic_vector (31 downto 0);
s_waitrequest : out std_logic;
m_addr : out integer range 0 to ram_size-1;
m_read : out std_logic;
m_readdata : in std_logic_vector (7 downto 0);
m_write : out std_logic;
m_writedata : out std_logic_vector (7 downto 0);
m_waitrequest : in std_logic;
test1: out std_logic_vector (5 downto 0);
test2: out std_logic_vector (5 downto 0)
);
end cache;
architecture arch of cache is
-- declare signals here
-- 15 bit signal will be of the following form: VDTTTTBBBBBWWbb
constant number_of_cache_lines: integer := 128;
TYPE t_cache_memory IS ARRAY(number_of_cache_lines-1 downto 0) OF STD_LOGIC_VECTOR(31 downto 0);
-- For data requested by CPU
signal tag_bits: std_logic_vector (5 downto 0);
signal block_index: std_logic_vector (4 downto 0);
signal block_index_int: integer;
signal word_index: std_logic_vector (1 downto 0);
signal word_index_int: integer;
-- For data in the cache
signal in_cache_tag_bits: std_logic_vector (5 downto 0);
signal in_cache_valid_bit: std_logic;
signal in_cache_dirty_bit: std_logic;
signal temp_s_addr: std_logic_vector(14 downto 0);
signal retrieved_address: std_logic_vector (31 downto 0);
type t_State is (readHit, writeHit, writeBack, readMiss, writeMiss, idle);
signal state: t_State;
signal cache_memory: t_cache_memory;
begin
-- For CPU address
temp_s_addr(3 downto 0) <= (others => '0');
temp_s_addr(14 downto 4) <= s_addr (14 downto 4);
tag_bits <= s_addr (14 downto 9);
block_index <= s_addr (8 downto 4);
block_index_int <= 4*to_integer(unsigned(block_index));
word_index <= s_addr (3 downto 2);
word_index_int <= to_integer(unsigned(word_index));
process (s_addr)
begin
if block_index_int /= -2147483648 then
retrieved_address <= cache_memory(block_index_int + word_index_int);
in_cache_valid_bit <= cache_memory(block_index_int)(15);
in_cache_dirty_bit <= cache_memory(block_index_int)(14);
in_cache_tag_bits <= cache_memory(block_index_int)(13 downto 8);
end if;
if s_read = '1' and s_write ='0' then
if in_cache_valid_bit = '1' then
test1 <= s_addr (14 downto 9);
test2 <= in_cache_tag_bits;
if in_cache_tag_bits = s_addr (14 downto 9) then
state <= readHit;
else
if in_cache_dirty_bit = '1' then
state <= writeBack;
else
state <= readMiss;
end if;
end if;
else
state <= readMiss;
end if;
elsif s_write = '1' and s_read = '0' then
if in_cache_valid_bit = '1' then
if tag_bits = in_cache_tag_bits then
state <= writeHit;
else
if in_cache_dirty_bit = '1' then
state <= writeBack;
else
state <= writeMiss;
end if;
end if;
end if;
else
state <= idle;
end if;
end process;
process(state)
begin
s_waitrequest <= '1';
case state is
-- If CPU is not doing anything
when idle =>
report "No Reads or Writes have occured.";
when readHit =>
report "Read Hit Occured:";
s_readdata <= retrieved_address;
-- If write hit
when writeHit =>
report "Write Hit Occured:";
cache_memory(block_index_int + word_index_int)(7 downto 0) <= s_addr(7 downto 0);
cache_memory(block_index_int)(13 downto 8) <= tag_bits;
cache_memory(block_index_int)(14) <= '1';
cache_memory(block_index_int)(15) <= '1';
cache_memory(block_index_int)(31 downto 16) <= (others => '0');
--state <= idle;
-- If cache hit but dirty bit then write-back
when writeBack =>
report "Write Back Occured:";
-- Write back into memory first
m_write <= '1';
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)));
m_writedata <= temp_s_addr(7 downto 0);
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0))) + 4;
m_writedata(3 downto 0) <= "0100";
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0))) + 8;
m_writedata(3 downto 0) <= "1000";
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0))) + 12;
m_writedata(3 downto 0) <= "1100";
m_write <= '0';
-- Write to cache
cache_memory(block_index_int)(13 downto 8) <= tag_bits;
cache_memory(block_index_int)(14) <= '0';
cache_memory(block_index_int)(15) <= '0';
cache_memory(block_index_int)(31 downto 16) <= (others => '0');
--state <= idle;
when readMiss =>
report "Read Miss Occured:";
m_read <= '1';
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)));
cache_memory(block_index_int)(7 downto 0) <= m_readdata;
cache_memory(block_index_int)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+4;
cache_memory(block_index_int+1)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+1)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+8;
cache_memory(block_index_int+2)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+2)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+12;
cache_memory(block_index_int+3)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+3)(31 downto 8) <= (others => '0');
m_read <= '0';
cache_memory(block_index_int)(13 downto 8) <= tag_bits;
cache_memory(block_index_int)(14) <= '0';
cache_memory(block_index_int)(15) <= '1';
cache_memory(block_index_int)(31 downto 16) <= (others => '0');
s_readdata<= cache_memory(block_index_int + word_index_int);
--state <= idle;
-- If write miss
when writeMiss =>
report "Write Miss Occured:";
m_write <= '1';
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0))) + word_index_int;
m_writedata <= s_addr(7 downto 0);
m_write <= '0';
m_read <= '1';
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)));
cache_memory(block_index_int)(7 downto 0) <= m_readdata;
cache_memory(block_index_int)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+4;
cache_memory(block_index_int+1)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+1)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+8;
cache_memory(block_index_int+2)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+2)(31 downto 8) <= (others => '0');
m_addr <= to_integer(unsigned(temp_s_addr(14 downto 0)))+12;
cache_memory(block_index_int+3)(7 downto 0) <= m_readdata;
cache_memory(block_index_int+3)(31 downto 8) <= (others => '0');
m_read <= '0';
cache_memory(block_index_int)(13 downto 8) <= tag_bits;
cache_memory(block_index_int)(14) <= '0';
cache_memory(block_index_int)(15) <= '1';
cache_memory(block_index_int)(31 downto 16) <= (others => '0');
--state <= idle;
end case;
s_waitrequest <= '0';
end process;
end arch;
Testbench Code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity cache_tb is
end cache_tb;
architecture behavior of cache_tb is
component cache is
generic(
ram_size : INTEGER := 32768
);
port(
clock : in std_logic;
reset : in std_logic;
-- Avalon interface --
s_addr : in std_logic_vector (31 downto 0);
s_read : in std_logic;
s_readdata : out std_logic_vector (31 downto 0);
s_write : in std_logic;
s_writedata : in std_logic_vector (31 downto 0);
s_waitrequest : out std_logic;
m_addr : out integer range 0 to ram_size-1;
m_read : out std_logic;
m_readdata : in std_logic_vector (7 downto 0);
m_write : out std_logic;
m_writedata : out std_logic_vector (7 downto 0);
m_waitrequest : in std_logic;
test1: out std_logic_vector (5 downto 0);
test2: out std_logic_vector (5 downto 0)
);
end component;
component memory is
GENERIC(
ram_size : INTEGER := 32768;
mem_delay : time := 10 ns;
clock_period : time := 1 ns
);
PORT (
clock: IN STD_LOGIC;
writedata: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
address: IN INTEGER RANGE 0 TO ram_size-1;
memwrite: IN STD_LOGIC;
memread: IN STD_LOGIC;
readdata: OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
waitrequest: OUT STD_LOGIC
);
end component;
-- test signals
signal reset : std_logic := '0';
signal clk : std_logic := '0';
constant clk_period : time := 1 ns;
signal s_addr : std_logic_vector (31 downto 0);
signal s_read : std_logic;
signal s_readdata : std_logic_vector (31 downto 0);
signal s_write : std_logic;
signal s_writedata : std_logic_vector (31 downto 0);
signal s_waitrequest : std_logic;
signal m_addr : integer range 0 to 2147483647;
signal m_read : std_logic;
signal m_readdata : std_logic_vector (7 downto 0);
signal m_write : std_logic;
signal m_writedata : std_logic_vector (7 downto 0);
signal m_waitrequest : std_logic;
signal test1: std_logic_vector (5 downto 0);
signal test2: std_logic_vector (5 downto 0);
begin
-- Connect the components which we instantiated above to their
-- respective signals.
dut: cache
port map(
clock => clk,
reset => reset,
s_addr => s_addr,
s_read => s_read,
s_readdata => s_readdata,
s_write => s_write,
s_writedata => s_writedata,
s_waitrequest => s_waitrequest,
m_addr => m_addr,
m_read => m_read,
m_readdata => m_readdata,
m_write => m_write,
m_writedata => m_writedata,
m_waitrequest => m_waitrequest,
test1 => test1,
test2 => test2
);
MEM : memory
port map (
clock => clk,
writedata => m_writedata,
address => m_addr,
memwrite => m_write,
memread => m_read,
readdata => m_readdata,
waitrequest => m_waitrequest
);
clk_process : process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
test_process : process
begin
REPORT "***Initializing***";
s_read <= '0';
s_write <= '0';
s_addr <= "00000000000000000000000000000000";
wait for clk_period;
report "Initializing Zero complete...";
report "***Start Testing***";
report "Read Miss Test:";
s_read <= '1';
s_write <= '0';
s_addr <= "11111111111111111111111110101111";
wait for clk_period;
assert s_readdata(7 downto 0) = m_readdata report "DATA NOT IN CACHE";
wait for clk_period;
report "Read Hit Test:";
s_read <= '1';
s_write <= '0';
s_addr <= "11111111111111111111111110101111";
wait for clk_period;
assert s_readdata(7 downto 0) = m_readdata report "DATA NOT IN CACHE";
wait for clk_period;
end process;
end;

Shifting a 7seg display on NEXYS 4 DDR

I have made a communication between a keyboard USB HID and Nexys 4 ddr. I have succeeded to output the letters I push(by decoding them and recoding in the letters I want to output), however I want to take it a step further and make the display so that when I push two letter I have the output"000000AB", for another letter pushed is "00000ABC" and so on.
I have tried to implement this idea by using a vector that I shift when my flag(the end bit from the data transmission) is 1(meaning a transmission ended) and coding the anode. However, my output is still the same, the whole segment displays the same letter.
My ps2receiver.
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity PS2Receiver is
Port ( clk : in STD_LOGIC;
kclk : in STD_LOGIC;
kdata : in STD_LOGIC;
outData : out STD_LOGIC_VECTOR (31 downto 0);
flg: out std_logic);
end PS2Receiver;
architecture Behavioral of PS2Receiver is
signal kclkf: std_logic;
signal kdataf: std_logic;
signal datacur: std_logic_vector(7 downto 0);
signal dataprev: std_logic_vector(7 downto 0);
signal cnt: std_logic_vector(3 downto 0):="0000";
signal keycode: std_logic_vector(31 downto 0):= (Others => '0');
signal flag: std_logic:='0';
component debouncer is
port(CLK: in std_logic;
I0: in std_logic;
I1: in std_logic;
O0: out std_logic;
O1:out std_logic );
end component;
begin
Deb: debouncer port map(clk=>clk,I0=>kclk,I1=>kdata,O0=>kclkf,O1=>kdataf);
--process(clk)
--begin
-- if falling_edge(kclkf) then
-- case cnt is
-- when "0000" => null ; --do nothing is the starting bit--0
-- when "0001" => datacur<="0000000" & kdataf;--1
-- when "0010" => datacur<="000000" & kdataf &"0";--2
-- when "0011" => datacur<="00000" & kdataf & "00";--3
-- when "0100" => datacur<="0000" & kdataf & "000";--4
-- when "0101" => datacur<="000" & kdataf & "0000";--5
-- when "0110" => datacur<="00" & kdataf & "00000";--6
-- when "0111" => datacur<="0" & kdataf & "000000";--7
--- when "1000" => datacur<= kdataf & "0000000";--8
-- when "1001" => flag<='1';--9
-- when "1010" => flag<='0';--10
-- when others=> NULL;
-- end case;-
-- if(cnt <= 9) then cnt<= cnt+1;
-- elsif cnt=10 then cnt<=(Others => '0');
-- end if;
-- end if;
--end process;
process(clk)
begin
if falling_edge(kclkf) then
case cnt is
when "0000" => null ; --do nothing is the starting bit--0
when "0001" => datacur<=datacur(7 downto 1) & kdataf;--1
when "0010" => datacur<=datacur(7 downto 2) & kdataf & datacur(0);--2
when "0011" => datacur<=datacur(7 downto 3) & kdataf & datacur(1 downto 0);--3
when "0100" => datacur<=datacur(7 downto 4) & kdataf & datacur(2 downto 0);--4
when "0101" => datacur<=datacur(7 downto 5) & kdataf & datacur(3 downto 0);---5
when "0110" => datacur<=datacur(7 downto 6) & kdataf & datacur(4 downto 0);--6
when "0111" => datacur<=datacur(7) & kdataf & datacur(5 downto 0);--7
when "1000" => datacur<= kdataf & datacur(6 downto 0);--8
when "1001" => flag<='1';--9
when "1010" => flag<='0';--10
when others=> NULL;
end case;
if(cnt <= 9) then cnt<= cnt+1;
elsif cnt=10 then cnt<=(Others => '0');
end if;
end if;
end process;
process(flag)
begin
if rising_edge(flag) then
if NOT(dataprev = datacur) then
keycode(31 downto 24)<= keycode(23 downto 16);
keycode(23 downto 16)<= keycode(15 downto 8);
keycode(15 downto 8)<= dataprev;
keycode(7 downto 0)<= datacur;
dataprev<= datacur;
end if;
end if;
end process;
flg<= flag;
outData<=keycode;
end Behavioral;
My main function
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity top is
Port (
Clk: in std_logic;
Rst: in std_logic;
PS2_clk: in std_logic;
PS2_data: in std_logic;
SEG: out std_logic_vector(7 downto 0);
AN: out std_logic_vector(7 downto 0);
DP: out std_logic;
UART_TXD: out std_logic
);
end top;
architecture Behavioral of top is
signal smallerCLK:std_logic:='0';
signal keycode: std_logic_vector(31 downto 0);
--signal PS2_clk: std_logic;
--signal PS2_data: std_logic;
component PS2RECEIVER is
Port ( clk : in STD_LOGIC;
kclk : in STD_LOGIC;
kdata : in STD_LOGIC;
outData : out STD_LOGIC_VECTOR (31 downto 0);
flg: out std_logic);
end component;
component DCD is
Port (
input: in std_logic_vector(7 downto 0);
CLK: in std_logic;
output: out std_logic_vector(31 downto 0)
);
end component DCD;
signal output: std_logic_vector(31 downto 0);
signal flag: std_logic;
begin
process(clk)
begin
if(rising_edge(clk)) then smallerCLK<=NOT smallerCLK;
end if;
end process;
PS2: PS2RECEIVER port map (smallerCLK,PS2_CLK,PS2_DATA,keycode,flag);
--DC:DCD port map(keycode(7 downto 0),smallerCLK,output);
display: entity WORK.displ7seg
port map(Clk => Clk,
Rst => Rst,
Data => keycode,
An => An,
Seg => Seg,
Dp=>Dp,
flag=> flag);
end Behavioral;
And the display:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
entity displ7seg is
Port ( Clk : in STD_LOGIC;
Rst : in STD_LOGIC;
Data : in STD_LOGIC_VECTOR (31 downto 0); -- datele pentru 8 cifre (cifra 1 din stanga: biti 31..28)
An : out STD_LOGIC_VECTOR (7 downto 0); -- selectia anodului activ
Seg : out STD_LOGIC_VECTOR (7 downto 0); -- selectia catozilor (segmentelor) cifrei active
Dp: out std_logic;
flag: in std_logic);
end displ7seg;
architecture Behavioral of displ7seg is
constant CNT_100HZ : integer := 2**20; -- divizor pentru rata de reimprospatare de ~100 Hz (cu un ceas de 100 MHz)
signal Num : integer range 0 to CNT_100HZ - 1 := 0;
signal NumV : STD_LOGIC_VECTOR (19 downto 0) := (others => '0');
signal LedSel : STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
signal Hex : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
signal AUX : std_logic_vector(7 downto 0);
signal anod : std_logic_vector(7 downto 0);
signal bufferBuffer: std_logic_vector(7 downto 0):="00000000";
signal MUX : std_logic_vector(2 downto 0) := (others => '0');
signal REG1, REG2, REG3, REG4,REG5,REG6,REG7,REG8 : std_logic_vector(7 downto 0) := (others => '1');
SIGNAL registerdisplay: std_logic_vector(31 downto 0):=(others=>'1');
SIGNAL date: std_logic_vector(63 downto 0):=(others=>'0');
--signal vet: std_logic_vector(7 downto 0) of std_logic_vector(7 downto 0);
begin
Dp <='1';
-- Proces pentru divizarea ceasului
divclk: process (Clk)
begin
if (rising_edge(clk)) then
if (Rst = '1') then
Num <= 0;
elsif (Num = CNT_100HZ - 1) then
Num <= 0;
else
Num <= Num + 1;
end if;
end if;
end process;
NumV <= CONV_STD_LOGIC_VECTOR (Num, 20);
LedSel <= NumV (19 downto 17);
-- Selectia anodului activ
Anod <= "11111110" when LedSel = "000" else
"11111101" when LedSel = "001" else
"11111011" when LedSel = "010" else
"11110111" when LedSel = "011" else
"11101111" when LedSel = "100" else
"11011111" when LedSel = "101" else
"10111111" when LedSel = "110" else
"01111111" when LedSel = "111" else
"11111111";
-- Selectia cifrei active
Hex <= Date (7 downto 0) when LedSel = "000" else
Date (15 downto 8) when LedSel = "001" else
Date (23 downto 16) when LedSel = "010" else
Date (31 downto 24) when LedSel = "011" else
Date (39 downto 32) when LedSel = "100" else
Date (47 downto 40) when LedSel = "101" else
Date (55 downto 48) when LedSel = "110" else
Date (63 downto 56) when LedSel = "111" else
"00000000";
-- Activarea/dezactivarea segmentelor cifrei active
process(clk)
begin
case HEX is
----gfedcba----
when "01000101"=> AUX <="11000000"; --0
when "00010110"=> AUX <="11111001"; --1
when "00011110"=> AUX <="10100100"; --2
when "00100110"=> AUX <="10110000"; --3
when "00100101"=> AUX <="10011011"; --4
when "00101110"=> AUX <="10010010"; --5
when "00110110"=> AUX <="10000010"; --6
when "00111101"=> AUX <="11111000"; --7
when "00111110"=> AUX <="10000000"; --8
when "01000110"=> AUX <="10010000"; --9
when "00011100"=> AUX <="10001000"; --A
when "00110010"=> AUX <="10000011"; --b
when "00100001"=> AUX <="11000110"; --C
when "00100011"=> AUX <="10100001"; --d
when "00100100"=> AUX <="10000110"; --E
when "00101011"=> AUX <="10001110"; --F
when "00110100"=> AUX <="10000010"; --G
when "00110011"=> AUX <="10001001"; --H
when "01000011"=> AUX <="11001111"; --I
when "00111011"=> AUX <="11110001"; --J
when "01000010"=> AUX <="10001111"; --K
when "01001011"=> AUX <="11000111"; --L
when "00111010"=> AUX <="11001000"; --M
when "00110001"=> AUX <="10101011"; --N
when "01000100"=> AUX <="11000000"; --O
when "01001101"=> AUX <="10001100"; --P
when "00010101"=> AUX <="10100001"; --Q
when "00101101"=> AUX <="10101111"; --r
when "00011011"=> AUX <="10010010"; --S
when "00101100"=> AUX <="10000111"; --t
when "00111100"=> AUX <="11000001"; --U
when "00101010"=> AUX <="11010101"; --V
when "00011101"=> AUX <="10011001"; --Y
when "00011010"=> AUX <="10100100"; --Z
when "00101001"=> AUX <="01110111"; -- Spaceend case
when others=> NULL;
end case;
end process;
PROCESS(CLK)-
BEGIN
if(rising_edge(clk)) then
if(flag=='1')then
Date (63 downto 56)<=Date(55 downto 48);
Date (55 downto 48) <= Date(47 downto 40);
Date (47 downto 40)<=Date(39 downto 32);
Date (39 downto 32)<= Date(31 downto 24);
Date (31 downto 24)<= Date(23 downto 16);
Date (23 downto 16) <=Date(15 downto 8);
Date (15 downto 8) <= Date(7 downto 0);
Date (7 downto 0) <=data(7 downto 0);
end if;
end if;
END PROCESS;
AN<=aNOD;
Seg<= AUX;
end Behavioral;
As of right now it is :https://imgur.com/a/kgfGnr2
I want to be able to see the keys I have pressed before and not have the same key all over my display.
Can somebody help me figure this out ?

vhdl: object subtype is not locally static

using GHDL to compile some VHDL getting a weird error. simulation compiler for VHDL fails on line: "case i_cli_adr is" with error message: "vhdl: object subtype is not locally static". How to fix it?
library ieee;
use ieee.std_logic_1164.all;
entity sim_regs is
generic(
LW : integer := 16
);
port(
i_sys_clk : in std_logic;
i_sys_rst_n : in std_logic;
i_cli_vld : in std_logic;
i_cli_wnr : in std_logic;
i_cli_adr : in std_logic_vector(LW-1 downto 0);
i_cli_dat : in std_logic_vector(LW-1 downto 0);
);
end entity;
architecture sim of sim_regs is
signal testreg0 : std_logic_vector(LW-1 downto 0);
signal testreg1 : std_logic_vector(LW-1 downto 0);
signal awrite : std_logic;
begin
awrite <= i_cli_vld and i_cli_wnr;
process(i_sys_clk)
begin
if (i_sys_clk = '1' and i_sys_clk'event) then
if (i_sys_rst_n = '0') then
testreg0 <= (others => '0');
testreg1 <= (others => '0');
end if;
else
o_cli_rvld <= '0';
if (awrite = '1') then
case i_cli_adr is
when 0 => testreg0 <= i_cli_dat;
when 1 => testreg1 <= i_cli_dat;
end case;
end if;
end if;
end process;
end architecture;
The fix was to hard code the size of address internally
architecture sim of sim_regs is
signal aaddr : std_logic_vector(15 downto 0);
begin
aaddr <= i_cli_adr and X"FFFF";
--- now can use aaddr in place of i_cli_adr in "case"
Complete Example:
library ieee;
use ieee.std_logic_1164.all;
use IEEE.numeric_std.all;
entity sim_regs is
generic(
LW : integer := 16
);
port(
i_sys_clk : in std_logic;
i_sys_rst_n : in std_logic;
i_cli_vld : in std_logic;
i_cli_wnr : in std_logic;
i_cli_adr : in std_logic_vector(LW-1 downto 0);
i_cli_dat : in std_logic_vector(LW-1 downto 0);
o_cli_rdat : out std_logic_vector(LW-1 downto 0);
o_cli_rvld : out std_logic;
i_cli_rbsy : in std_logic
);
end entity;
architecture sim of sim_regs is
signal testreg0 : std_logic_vector(LW-1 downto 0);
signal testreg1 : std_logic_vector(LW-1 downto 0);
signal testreg2 : std_logic_vector(LW-1 downto 0);
signal testreg3 : std_logic_vector(LW-1 downto 0);
signal aaddr : std_logic_vector(15 downto 0);
signal awrite : std_logic;
signal aread : std_logic;
begin
awrite <= i_cli_vld and i_cli_wnr;
aread <= i_cli_vld and not i_cli_wnr and not i_cli_rbsy;
aaddr <= i_cli_adr and X"FFFF";
process(i_sys_clk)
begin
if (i_sys_clk = '1' and i_sys_clk'event) then
if (i_sys_rst_n = '0') then
o_cli_rvld <= '0';
o_cli_rdat <= (others => '0');
testreg0 <= (others => '0');
testreg1 <= (others => '0');
testreg2 <= (others => '0');
testreg3 <= (others => '0');
end if;
else
o_cli_rvld <= '0';
if (awrite = '1') then
case aaddr is
when X"0000" => testreg0 <= i_cli_dat;
when X"0001" => testreg1 <= i_cli_dat;
when X"0002" => testreg2 <= i_cli_dat;
when X"0003" => testreg3 <= i_cli_dat;
when others => null;
end case;
elsif (aread = '1') then
o_cli_rvld <= '1';
case aaddr is
when X"0000" => o_cli_rdat <= testreg0;
when X"0001" => o_cli_rdat <= testreg1;
when X"0002" => o_cli_rdat <= testreg2;
when X"0003" => o_cli_rdat <= testreg3;
when others => o_cli_rdat <= (others => '0');
end case;
end if;
end if;
end process;
end architecture;

i have a vhdl code that take a 16 bit binary converts it to 5 bcd(4bit) how can i connect each bcd with a display?

i have a code that take a 16 bit binary converts it to 5 bcd(4bit)
how can i connect each bcd with a display?
the bcd 0 has to connect to the display 0 (seven segment display) so that the binary number is going to convert to decimal and display it on 5 seven segment displays
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity binary_bcd is
generic(N: positive := 16);
port(
clk, reset: in std_logic;
binary_in: in std_logic_vector(N-1 downto 0);
bcd0, bcd1, bcd2, bcd3, bcd4: out std_logic_vector(3 downto 0)
);
end binary_bcd ;
architecture behaviour of binary_bcd is
type states is (start, shift, done);
signal state, state_next: states;
signal binary, binary_next: std_logic_vector(N-1 downto 0);
signal bcds, bcds_reg, bcds_next: std_logic_vector(19 downto 0);
-- output register keep output constant during conversion
signal bcds_out_reg, bcds_out_reg_next: std_logic_vector(19 downto 0);
-- need to keep track of shifts
signal shift_counter, shift_counter_next: natural range 0 to N;
begin
process(clk, reset)
begin
if reset = '1' then
binary <= (others => '0');
bcds <= (others => '0');
state <= start;
bcds_out_reg <= (others => '0');
shift_counter <= 0;
elsif falling_edge(clk) then
binary <= binary_next;
bcds <= bcds_next;
state <= state_next;
bcds_out_reg <= bcds_out_reg_next;
shift_counter <= shift_counter_next;
end if;
end process;
convert:
process(state, binary, binary_in, bcds, bcds_reg, shift_counter)
begin
state_next <= state;
bcds_next <= bcds;
binary_next <= binary;
shift_counter_next <= shift_counter;
case state is
when start =>
state_next <= shift;
binary_next <= binary_in;
bcds_next <= (others => '0');
shift_counter_next <= 0;
when shift =>
if shift_counter = N then
state_next <= done;
else
binary_next <= binary(N-2 downto 0) & 'L';
bcds_next <= bcds_reg(18 downto 0) & binary(N-1);
shift_counter_next <= shift_counter + 1;
end if;
when done =>
state_next <= start;
end case;
end process;
bcds_reg(19 downto 16) <= bcds(19 downto 16) + 3 when bcds(19 downto 16) > 4 else
bcds(19 downto 16);
bcds_reg(15 downto 12) <= bcds(15 downto 12) + 3 when bcds(15 downto 12) > 4 else
bcds(15 downto 12);
bcds_reg(11 downto 8) <= bcds(11 downto 8) + 3 when bcds(11 downto 8) > 4 else
bcds(11 downto 8);
bcds_reg(7 downto 4) <= bcds(7 downto 4) + 3 when bcds(7 downto 4) > 4 else
bcds(7 downto 4);
bcds_reg(3 downto 0) <= bcds(3 downto 0) + 3 when bcds(3 downto 0) > 4 else
bcds(3 downto 0);
bcds_out_reg_next <= bcds when state = done else
bcds_out_reg;
bcd4 <= bcds_out_reg(19 downto 16);
bcd3 <= bcds_out_reg(15 downto 12);
bcd2 <= bcds_out_reg(11 downto 8);
bcd1 <= bcds_out_reg(7 downto 4);
bcd0 <= bcds_out_reg(3 downto 0);
end behaviour;
test bench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb_bcd IS
END tb_bcd;
ARCHITECTURE behavior OF tb_bcd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT binary_bcd
PORT(
clk : IN std_logic;
reset : IN std_logic;
binary_in : IN std_logic_vector(15 downto 0);
bcd0 : OUT std_logic_vector(3 downto 0);
bcd1 : OUT std_logic_vector(3 downto 0);
bcd2 : OUT std_logic_vector(3 downto 0);
bcd3 : OUT std_logic_vector(3 downto 0);
bcd4 : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal binary_in : std_logic_vector(15 downto 0) := (others => '0');
--Outputs
signal bcd0 : std_logic_vector(3 downto 0);
signal bcd1 : std_logic_vector(3 downto 0);
signal bcd2 : std_logic_vector(3 downto 0);
signal bcd3 : std_logic_vector(3 downto 0);
signal bcd4 : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: binary_bcd PORT MAP (
clk => clk,
reset => reset,
binary_in => binary_in,
bcd0 => bcd0,
bcd1 => bcd1,
bcd2 => bcd2,
bcd3 => bcd3,
bcd4 => bcd4
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
reset <= '1';
wait for 100 ns;
reset <= '0';
binary_in <= "0000000000001111";
wait for 200 ns;
binary_in <= "0000000001001111";
wait for 200 ns;
binary_in <= "0000000001111111";
wait for 200 ns;
binary_in <= "0000111101001111";
wait for 2000 ns;
end process;
END;

Implementing a 10 bit shift register with led outputs

I am trying to implement the the following shift register
entity MyShiftRegister is
port(
clock: in std_logic;
DataIn: in std_logic_vector (9 downto 0);
Left: in std_logic; --synchronous left rotate
Right: in std_logic; --synchronous right rotate
Load: in std_logic; --synchronous parallel load
Clear: in std_logic; -- synchronous clear
DataOut: out std_logic_vector (9 downto 0);
This is what I have so far
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity question2 is
Port (
led: buffer std_logic_vector (9 downto 0);
clk: in std_logic;
btnu: in std_logic;
btnL: in std_logic;
btnR: in std_logic ;
btnD: in std_logic;
btnC: in std_logic
);
end question2;
architecture Behavioral of question2 is
constant active: std_logic :='1';
constant inactive: std_logic :='0';
constant step_zero: std_logic_vector(9 downto 0) :="0000000000";
constant step_one: std_logic_vector(9 downto 0) :="0000000001";
constant step_two: std_logic_vector(9 downto 0) :="0000000010";
constant step_three: std_logic_vector(9 downto 0) :="0000000100";
constant step_four: std_logic_vector(9 downto 0) :="0000001000";
constant step_five: std_logic_vector(9 downto 0) :="0000010000";
constant step_six: std_logic_vector(9 downto 0) :="0000100000";
constant step_seven: std_logic_vector(9 downto 0) :="0001000000";
constant step_eight: std_logic_vector(9 downto 0) :="0010000000";
constant step_nine: std_logic_vector(9 downto 0) :="0100000000";
constant step_ten: std_logic_vector(9 downto 0) :="0100000000";
signal DataIn: std_logic_vector (9 downto 0):= "1111111111";
signal Load: std_logic := btnD;
signal Reset: std_logic;
signal Left: std_logic:= btnL;
signal Right: std_logic:= btnR;
signal DataOut: std_logic_vector := led (9 downto 0);
signal Clear: std_logic:= btnU;
signal speed_enable: std_logic;
begin
SpeedControl: process (clk)
variable counter: integer range 0 to 10000000;
begin
speed_enable<=not active;
if Reset = Active then
counter:= 0;
elsif (rising_edge (clk)) then
counter := counter + 1;
if (counter=10000000) then
speed_enable<= Active;
counter:=0;
end if;
end if;
end process;
shiftregister: process(clk, clear)
begin
if rising_edge (clk) then
if clear= active then
DataOut <= (others => '0');
elsif load = active then
DataOut <= DataIn ;
elsif Left = active then
DataOut <= DataOut(8 downto 0) & "1" ;
if DataOut = "1000000000" then
clear <= active;
elsif Right = active then
DataOut <= DataOut (9 downto 1) & "1" ;
if DataOut = "0000000001" then
clear <= active;
end if;
end if;
end if;
end if;
end process;
with DataOut select
led <= step_one when "0000",
step_two when "0001",
step_three when "0010",
step_four when "0011",
step_five when "0100",
step_six when "0101",
step_seven when "0110",
step_eight when "0111",
step_nine when "1000",
step_ten when "1001",
step_zero when others;
end Behavioral;
How exactly do I rotate bits left and right and tie that to my led outputs. I was thinking of using a counter and just incrementing and decrementing to shift bits left or right but I'm not sure if that would still be considered a shift register.
thanks
To start:
constant step_nine: std_logic_vector(9 downto 0) :="0100000000";
constant step_ten: std_logic_vector(9 downto 0) :="0100000000";
is incorrect. It should be
constant step_nine: std_logic_vector(9 downto 0) :="0100000000";
constant step_ten: std_logic_vector(9 downto 0) :="1000000000";
But this approach is very error prone anyhow. Lets simplify it:
process(sel)
variable selected_led : natural;
begin
led <= (others => '0');
selected_led := to_integer(unsigned(sel));
if selected_led < led'length then
led(selected_led) <= '1';
end if;
end process;
If the led(selected_led) <= '1'; won't synthesize, you probably have to change it to
for i in 0 to led'length-1 loop
if (i = selected_led) then
led(i) <= '1';
end if;
end loop;
As for using the buffer port. Don't. preferably only use in or out. If you want to read an out port, compile with VHDL-2008, or use a temporary signal in between.
Then note that right and left are keywords in VHDL. you shouldn't use them
What you want is very simple and basic VHDL. Example (using VHDL-2008):
process(clock)
begin
if rising'edge(clock) then
if clear = '1' then
data_out <= (others => '0');
elsif load = '1' then
data_out <= data_in;
elsif right_rotate = '1' then
data_out <= data_out(0) & data_out(data_out'length-1 downto 1);
elsif left_rotate = '1' then
data_out <= data_out(data_out'length-2 downto 0) &
data_out(data_out'length-1);
end if;
end if;
end process;

Resources