VHDL map for each bit in a vector - loops

Whats the best way to perform a port map for each bit in a vector? Say I have a vector representing a series of buttons, and wish to debounce each one using a bebounce module, how should I go about that?
Right now I have the following, but I believe there should be a better way
entity ButtonDebouncer is
Port (
clock : in std_logic;
buttons : in std_logic_vector(0 to 5);
--{ more stuff }
);
end ButtonDebouncer;
architecture Behavioral of ButtonDebouncer is
signal bufferedButtons : std_logic_vector(0 to 5) := (others => '0');
begin
c1: entity debounce port map (Clock, buttons(0), bufferedButtons(0));
c2: entity debounce port map (Clock, buttons(1), bufferedButtons(1));
c3: entity debounce port map (Clock, buttons(2), bufferedButtons(2));
c4: entity debounce port map (Clock, buttons(3), bufferedButtons(3));
c5: entity debounce port map (Clock, buttons(4), bufferedButtons(4));
c6: entity debounce port map (Clock, buttons(5), bufferedButtons(5));
--{ Do stuff with debounced buttons }
end Behavioral;

For generate would be a good candidate construct here.
entity ButtonDebouncer is
Port (
clock : in std_logic;
buttons : in std_logic_vector(0 to 5);
--{ more stuff }
);
end ButtonDebouncer;
architecture Behavioral of ButtonDebouncer is
signal bufferedButtons : std_logic_vector(0 to 5) := (others => '0');
begin
debouncers: for i in 0 to 5 generate
c1: entity debounce port map (Clock, buttons(i), bufferedButtons(i));
end generate;
--{ Do stuff with debounced buttons }
end Behavioral;

Travis' solution is a good starting point.
I would go one step further and implement a debounce module for multiple bits. So you can pass a whole button vector to this module.
entity debounce is
generic (
BITS : POSITIVE
);
port (
Clock : STD_LOGIC;
Input : STD_LOGIC_VECTOR(BITS - 1 downto 0);
Output : STD_LOGIC_VECTOR(BITS - 1 downto 0)
)
end entity;
architecture rtl of debounce is
-- define 'global' signals here (per instance)
begin
genDebounce : for i in 0 to BITS - 1 generate
-- define 'local' signals here (per debounce circuit)
begin
-- debounce circuit
end generate;
end architecture;
Usage:
debButtons : entity work.debounce
generic map (
BITS => buttons'length
)
port map (
Clock => Clock,
Input => Buttons,
Output => bufferedButtons
);

Related

Reading from mouse inputs in Ada

I have a procedure in Ada which reads from a touch screen input. The code is very old and I do not have the touch screen anymore. I would like to replace the touch screen code with reading from a mouse input. Would it be simpler to write the function in C and Import it into the Ada code? The code below is the touch screen code.
HIL_NAME : STRING (1.. 10) := "/dev/touch";
procedure READ (X, Y : out INTEGER) is
type BYTE is new INTEGER range 0 .. 255;
for BYTE'SIZE use 8;
package IN_IO is new SEQUENTIAL_IO (BYTE);
use IN_IO;
type DATA_TYPE is array (2 .. 9) of BYTE;
HIL_FILE : IN_IO.FILE_TYPE;
COUNT : BYTE;
DATA : DATA_TYPE;
begin
IN_IO.OPEN (HIL_FILE, IN_FILE, HIL_NAME); -- open the touchscreen
loop
IN_IO.READ (HIL_FILE, COUNT); -- read the incoming record size
-- read the incoming record
for I in INTEGER range 2 .. BYTE'POS (COUNT) loop
IN_IO.READ (HIL_FILE, DATA (I));
end loop;
-- is this a fingerdown? overkill test.
if ((COUNT = 9) and (DATA (6) = 2#01000010#) and (DATA (9) = 142)) then
X := BYTE'POS (DATA (7)); -- pick out coordinates
Y := BYTE'POS (DATA (8));
IN_IO.CLOSE (HIL_FILE); -- close touchscreen to flush buffer
return; -- return to caller
end if;
end loop;
end READ;
It would be useful to know OS, version, compiler, window manager toolkit and version. For example I'm running Debian 10, and with Gnome 3 as my WM I can most easily access the mouse using the GTKAda toolkit. Last time I wrote code directly accessing a mouse was on DOS, in Modula-2.
However, GTKAda is not particularly easy to learn...
If you're willing to use a web browser as the GUI to your app (which also helps portability across systems ... you might even run the app on a PC but access it via a tablet or phone, giving you a touchscreen!) I recommend looking at Gnoga available from www.gnoga.com. Take a look at some of its tutorials, they should be easy to build and get you started accessing mouse and simple drawing.
EDIT
Having found the magic words (Centos, ncurses) in various comments (which you could usefully add to the question, in case there are better answers) what you are looking for is an Ada binding to ncurses such as this one. This binding is part of the official ncurses source since version 5.8 so should already be available on Centos.
It should then be a simple matter of writing a Read procedure which calls the ncurses mouse handling package, returning mouse position (scaled to an 8-bit Integer or Natural, and probably offset from the console window origin) whenever the LH button is pressed, otherwise presumably returning ... whatever an OUT parameter is initialised to, (presumably BYTE'FIRST)
Job done.
Now we can see the touch screen filename si part of the /dev/ hierarchy it may be even simpler to see if there is any mileage in finding documentation on /dev/mouse as #zerte suggests (or /dev/input/mouse[0|1] on my laptop) ... but I think ncurses will be less machine-dependent.
I have solved the problem using Ncurses. I downloaded the terminal-interface-curses and used the files to create the following procedure.
with Terminal_Interface.Curses;
use Terminal_Interface.Curses;
tmp2 : Event_Mask;
c : Key_Code;
firsttime : Bollean;
procedure READ (X1 : out Column_Position;
Y1 : Line_Position) is
begin
tmp2 := Start_Mouse (All_Events);
c:= Character'Pos ('?');
Set_Raw_Mode (SwitchOn => True);
Set_KeyPad_Mode (SwitchOn => True);
firsttime := true;
loop
if not firsttime then
if c = KeyMouse then
declare
event : Mouse_Event;
Y : Line_Position;
X : Column_Position;
Button : Mouse_Button;
State : Mouse_State;
begin
event := Get_Mouse;
Get_Event (event, Y, X, Button, State);
X1 := X;
Y1 := Y;
exit;
end;
end if;
end if;
firsttime := False;
loop
c := Get_Keystroke;
exit when c /= Key_None;
end loop;
end loop;
End_Mouse (tmp2);
end READ;
You can read the mouse by using the Linux input subsystem (as was suggested by #Zerte). See also this question on SO and some kernel documentation here and here. Reading the mouse' input doesn't seem hard (at least not on a Raspberry Pi 3 running Raspbian GNU/Linux 10). Of course, you still need to apply proper scaling and you need to figure out the device that exposes the mouse events (in my case: /dev/input/event0)
NOTE: You can find the number by inspecting the output of sudo dmesg | grep "input:". If a mouse (or other pointing device) is connected to inputX, then the events of this device will be exposed on eventX.
main.adb
with Ada.Text_IO;
with Ada.Sequential_IO;
with Interfaces.C;
procedure Main is
package C renames Interfaces.C;
use type C.unsigned_short;
use type C.int;
-- Input event codes (linux/input-event-codes.h)
EV_SYN : constant := 16#00#;
EV_KEY : constant := 16#01#;
EV_REL : constant := 16#02#;
EV_ABS : constant := 16#03#;
EV_MSC : constant := 16#04#;
BTN_MOUSE : constant := 16#110#;
BTN_LEFT : constant := 16#110#;
BTN_RIGHT : constant := 16#111#;
BTN_MIDDLE : constant := 16#112#;
REL_X : constant := 16#00#;
REL_Y : constant := 16#01#;
REL_WHEEL : constant := 16#08#;
-- Time value (sys/time.h)
subtype suseconds_t is C.long;
subtype time_t is C.long;
type timeval is record
tv_sec : time_t;
tv_usec : suseconds_t;
end record;
pragma Convention (C, timeval);
-- Input event struct (linux/input.h)
type input_event is record
time : timeval;
typ : C.unsigned_short;
code : C.unsigned_short;
value : C.int;
end record;
pragma Convention (C, input_event);
-- ... and a package instantiation for sequential IO.
package Input_Event_IO is new Ada.Sequential_IO (input_event);
use Input_Event_IO;
File : File_Type;
Event : input_event;
-- Position of the mouse and wheel.
X, Y, W : C.int := 0;
begin
Open (File, In_File, "/dev/input/event0");
-- Infinite loop, use Ctrl-C to exit.
loop
-- Wait for a new event.
Read (File, Event);
-- Process the event.
case Event.typ is
when EV_SYN =>
Ada.Text_IO.Put_Line
(X'Image & "," & Y'Image & " [" & W'Image & "]");
when EV_KEY =>
case Event.code is
when BTN_LEFT =>
Ada.Text_IO.Put_Line ("Left button.");
when BTN_MIDDLE =>
Ada.Text_IO.Put_Line ("Middle button.");
when BTN_RIGHT =>
Ada.Text_IO.Put_Line ("Right button.");
when others =>
null;
end case;
when EV_REL =>
case Event.code is
when REL_X =>
X := X + Event.value;
when REL_Y =>
Y := Y + Event.value;
when REL_WHEEL =>
W := W + Event.value;
when others =>
null;
end case;
when EV_ABS =>
case Event.code is
when REL_X =>
X := Event.value;
when REL_Y =>
Y := Event.value;
when REL_WHEEL =>
W := Event.value;
when others =>
null;
end case;
when others =>
null;
end case;
end loop;
end Main;
output (running on a headless RPi 3)
pi#raspberrypi:~/mouse $ sudo obj/main
[...]
-85, 9 [-5]
-84, 9 [-5]
-83, 9 [-5]
Left button.
-83, 9 [-5]
Left button.
-83, 9 [-5]
Left button.
-83, 9 [-5]
Left button.
-83, 9 [-5]
Right button.
-83, 9 [-5]
Right button.
-83, 9 [-5]
Middle button.
-83, 9 [-5]
Middle button.
-83, 9 [-5]
-84, 9 [-5]
^C
pi#raspberrypi:~/mouse $

convert fixed size array to record of same size

This might be a nobrainer but as a novice i can not get my head around it.
I have a function returning a fixed size array. I am trying to convert this array into a record of the same size
The function signature is like this:
type Control is new UInt8_Array (1 .. 2);
function readControl (Command : Control) return Control;
I am trying to get the two bytes (UInt8) into the record Contro_Status_Bytes with the following definition:
type Control_Status_MSB is
record
RES_UP : Boolean;
QMAX_UP : Boolean;
BCA : Boolean;
CCA : Boolean;
CALMODE : Boolean;
SS : Boolean;
WDRESET : Boolean;
SHUTDOWNEN : Boolean;
end record;
for Control_Status_MSB use
record
RES_UP at 0 range 0 .. 0;
QMAX_UP at 0 range 1 .. 1;
BCA at 0 range 2 .. 2;
CCA at 0 range 3 .. 3;
CALMODE at 0 range 4 .. 4;
SS at 0 range 5 .. 5;
WDRESET at 0 range 6 .. 6;
SHUTDOWNEN at 0 range 7 .. 7;
end record;
type Control_Status_LSB is
record
VOK : Boolean;
RUP_DIS : Boolean;
LDMD : Boolean;
SLEEP : Boolean;
HIBERNATE : Boolean;
INITCOMP : Boolean;
end record;
for Control_Status_LSB use
record
VOK at 0 range 1 .. 1;
end record;
type Control_Status_Bytes is
record
HighByte : Control_Status_MSB;
LowByte : Control_Status_LSB;
end record;
I think it must be possible to convert the array to the record and vice versa without an unchecked conversion. But currently i am missing something.
Update: This might be an valid answer/way to do that i came up after reading #Simons answer.
function readControl (Command : Control) return Control_Status_Bytes is
CSB : Control_Status_Bytes;
begin
-- do stuff return UInt8_Array of size 2 as response
CSB.HighByte := response'First;
CSB.LowByte := response'Last;
return CSB;
end readControl;
Unchecked conversion is the usual way.
But for I/O ports and peripheral registers in MCUs (Atmel AVR, MSP430 etc) which can be addressed either as numbers, or arrays of booleans (or potentially, records) there's a hack ...
p1in : constant unsigned_8; -- Port 1 Input
Pragma Volatile(p1in);
Pragma Import(Ada, p1in); -- see ARM C.6 (13)
For p1in'Address use 16#20#;
p1in_bits : constant Byte; -- Port 1 Input Bits
Pragma Volatile(p1in_bits);
Pragma Import(Ada, p1in_bits);
For p1in_bits'Address use 16#20#;
This maps the inputs from I/O port 1 to the same address, viewed either as an 8 bit Unsigned or as a Byte (an array of 8 booleans).
The equivalent in your case would be something like
For Control_Status_Record'Address use Control_Status_Array`Address;
Note you probably need to attach "pragma volatile" to both views, as here, so that changes to one view aren't lost because the other view is cached in a register.
All in all, I recommend Unchecked_Conversion over this approach. It's designed for the job and avoids messing with Volatile.
It has to depend on what happens inside readControl, but couldn't you make it return the type you want directly?
function readControl (Command : Control) return Control_Status_Bytes;
(I expect that Command actually has some structure too?).
By the way, you only define the position of one component (VOK) in Control_Status_LSB, which leaves the rest up to the compiler.
The hint from #Simon Wright pointed me in the right direction.
This is what is use now and it works:
function convert (ResponseArray : Control) return Control_Status_Bytes is
Result : Control_Status_Bytes with
Import, Convention => Ada, Address => ResponseArray'Address;
begin
return Result;
end convert;

<*> of the instance <gen[1].*> is unconnected or connected to loadless signal

when I'm synthesizing the following VHDL code I get the above error(s).
This is a toplevel design to connect multiple entities.
The component declaration:
COMPONENT channel_memory IS
PORT (
clka : IN STD_LOGIC;
rsta : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0):= (OTHERS => '0');
addra : IN STD_LOGIC_VECTOR(11 DOWNTO 0):= (OTHERS => '0');
dina : IN STD_LOGIC_VECTOR(15 DOWNTO 0):= (OTHERS => '0');
douta : OUT STD_LOGIC_VECTOR(15 DOWNTO 0):= (OTHERS => '0')
);
END COMPONENT;
COMPONENT MAX5190 IS
PORT (
GCLK : IN STD_LOGIC; -- CLK in 200 MHz
RSTN : IN STD_LOGIC; -- Reset
OUTPUT_TRIGGER : IN STD_LOGIC; -- Enable the module (from controller)
TRIGGER_CHIRP : IN STD_LOGIC; -- Start chirping (from channel delay)
LOAD_ACK : IN STD_LOGIC; -- Data ready
DATA_LENGTH : IN STD_LOGIC_VECTOR (11 DOWNTO 0); -- Total words to send to DAC
DIN : IN STD_LOGIC_VECTOR (15 DOWNTO 0) := (OTHERS => '0'); -- Actual data to send to DAC
CHIRP_EN_TRIGGER : IN STD_LOGIC; -- Enable dac >> ××××××××××××
-- ×
-- Memory block ×
LOAD_OUTPUT : OUT STD_LOGIC; -- Request data ×
DATA_ADDR : OUT STD_LOGIC_VECTOR (11 DOWNTO 0); -- Adress to read from ×
-- ×
CHIRP_EN : OUT STD_LOGIC; -- opamp enable << ××××××××××
-- MAX5190 outputs
DAC_EN : OUT STD_LOGIC; -- DAC Enable (always high)
DAC_CS : OUT STD_LOGIC; -- DAC chip select
DAC_CLK : OUT STD_LOGIC; -- DAC clock out
DAC_DATA : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) := (OTHERS => '0') -- dac data
);
END COMPONENT;
COMPONENT memory_controll IS
PORT(
CLK : IN STD_LOGIC;
-- from controller
DATA_IN : IN STD_LOGIC_VECTOR ( 15 DOWNTO 0 ); -- data to store
DATA_LENGTH : in STD_LOGIC_VECTOR ( 11 DOWNTO 0 ); -- number of words to store
RESET : IN STD_LOGIC; -- reset module
NEW_DATA : IN STD_LOGIC; -- new data available flag
WRITE_ENABLE : IN STD_LOGIC; -- enable writing
-- from MAX5190
ADDRESS_SELECT : IN STD_LOGIC_VECTOR ( 11 DOWNTO 0 ) := (others => '0'); -- addres selected by MAX5190 driver
REQUEST_DATA : IN STD_LOGIC; -- request data
DATA_OUT : OUT STD_LOGIC_VECTOR ( 15 DOWNTO 0 ); -- data to MAX5190 driver
DATA_READY : OUT STD_LOGIC; -- data to MAX5190 driver ready
-- to memory
DOUTA : IN STD_LOGIC_VECTOR ( 15 DOWNTO 0 ) := (others => '0'); -- data from memory
DINA : OUT STD_LOGIC_VECTOR ( 15 DOWNTO 0 ); -- data to memory
ADDRA : OUT STD_LOGIC_VECTOR ( 11 DOWNTO 0 ); -- addres to write or read
WEA : OUT STD_LOGIC_VECTOR ( 0 DOWNTO 0); -- write enable
RSTA : OUT STD_LOGIC -- reset memory
);
The port mapping:
gen: for i in 1 to number_of_channels generate
-- memory controll
memcont: memory_controll
PORT MAP(
CLK => clk400MHz,
-- from controller
DATA_IN => MEMORY_CONTROL_DATA,
DATA_LENGTH => MEMORY_CONTROL_DATA_LENGTH,
RESET => BUTTON,
NEW_DATA => MEMORY_CONTROL_NEW_DATA,
WRITE_ENABLE => MEMORY_CONTROL_WRITE_ENABLE,
-- from MAX5190
ADDRESS_SELECT => ADDRESS_SELECT (i),
REQUEST_DATA => REQUEST_DATA (i),
DATA_OUT => DATA_OUT (i),
DATA_READY => DATA_READY (i),
-- to memory
DOUTA => DOUTA (i),
DINA => DINA (i),
ADDRA => ADDRA (i),
WEA => WEA (i),
RSTA => RSTA (i)
);
-- max5190
max: max5190
PORT MAP(
GCLK => clk200MHz,
RSTN => MAX5190_RESET,
OUTPUT_TRIGGER => MAX5190_ENABLE,
TRIGGER_CHIRP => TRIGGER_CHIRP (i),
LOAD_ACK => DATA_READY (i),
DATA_LENGTH => MAX5190_DATA_LENGTH,
DIN => DATA_OUT (i),
CHIRP_EN_TRIGGER => MAX5190_CHIRP_ENABLE,
-- Memory block
LOAD_OUTPUT => REQUEST_DATA (i),
DATA_ADDR => ADDRESS_SELECT (i),
CHIRP_EN => CHIRP_EN (i),
-- MAX5190 outputs
DAC_EN => DAC_EN (i),
DAC_CS => DAC_CS (i),
DAC_CLK => CHANNEL_CLKS (i),
DAC_DATA => CHANNELS (i)
);
-- memory
mem: channel_memory
PORT MAP(
clka => clk400MHz,
rsta => BUTTON,
wea => WEA (i),
addra => ADDRA (i),
dina => DINA (i),
douta => DOUTA (i)
);
the package where I declared my types:
PACKAGE jelle IS
FUNCTION lookup (input: STD_LOGIC_VECTOR(15 DOWNTO 0)) RETURN INTEGER;
FUNCTION jOR (input: STD_LOGIC_VECTOR( 7 DOWNTO 0)) RETURN STD_LOGIC;
TYPE VECTOR_ARRAY is array (POSITIVE) of STD_LOGIC_VECTOR( 7 downto 0);
TYPE ADDRESS_ARRAY is array (POSITIVE) of STD_LOGIC_VECTOR(11 downto 0);
TYPE DATA_ARRAY is array (POSITIVE) of STD_LOGIC_VECTOR(15 downto 0);
TYPE WEA_ARRAY is array (POSITIVE) of STD_LOGIC_VECTOR( 0 downto 0);
END PACKAGE;
The previous time I synthesized the code these where warning, now they've changed to errors, but I think they're still pretty important.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 288: Output port <CLK_OUT3> of the instance <dcm> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 288: Output port <LOCKED> of the instance <dcm> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 296: Output port <MAX5190_CHIRP_ENABLE_TRIGGER> of the instance <contr> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 365: Output port <DATA_OUT> of the instance <gen[1].memcont> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 365: Output port <DINA> of the instance <gen[1].memcont> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 365: Output port <ADDRA> of the instance <gen[1].memcont> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 365: Output port <WEA> of the instance <gen[1].memcont> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 365: Output port <RSTA> of the instance <gen[1].memcont> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 391: Output port <DATA_ADDR> of the instance <gen[1].max> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 391: Output port <DAC_DATA> of the instance <gen[1].max> is unconnected or connected to loadless signal.
INFO:Xst:3210 - "E:\Projects\VHDL\New_Phase\toplevel.vhd" line 414: Output port <douta> of the instance <gen[1].mem> is unconnected or connected to loadless signal.
These errors repeat themselves for every generated object.
The input ports are given default values because the compiler kept asking for it with errors (don't know why either though).
If anyone could help me that would be fantastic!!
The signal that are connected to the instantiated modules are simply not used, thus for example the message "Output port <DATA_OUT> of the instance <gen[1].memcont> is unconnected or connected to loadless signal".
So take a look at modules where the components are instantiated, or a module above, connect the output from the instantiated modules, since the output is probably there to be used ;-)

Testbench For Entitiy with package - VHDL

I have problems in creating a testbench for my test module that used package.
The package just contains a block of array which is accessed in different process.
-------------------- Package ---------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package my_array_pkg is
type my_array is array ( 0 to 9) of std_logic_vector(3 downto 0);
end my_array_pkg;
And the top entity.
----------------- TOP ENTITY -------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.my_array_pkg.all;
use IEEE.NUMERIC_STD.ALL;
entity pkt_top is
Port ( sys_clk : IN STD_LOGIC;
RESET : IN STD_LOGIC;
AN_EN : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
Seg_Cathodes : out Std_logic_Vector(6 downto 0)
);
end pkt_top;
architecture Behavioral of pkt_top is
SIGNAL CLK1HZ, CLK256HZ : STD_LOGIC;
signal my_digit : my_array;
COMPONENT Clock_1Hz is
Port ( Sys_clk : in STD_LOGIC;
Reset : in std_logic;
C_256Hz : out std_logic;
C_1Hz : out std_logic
);
end COMPONENT;
COMPONENT Array_Count is
Port ( C_1Hz : in std_logic;
reset : in std_logic;
digit : out my_array
);
end COMPONENT;
COMPONENT Display_Driver is
Port ( Reset : in std_logic;
c256Hz : in std_logic;
C_1Hz : in std_logic;
digit_in : in my_array;
Seg_Cathodes : out Std_logic_vector(6 downto 0);
An_En : out std_logic_vector(3 downto 0)
);
end COMPONENT;
begin
C1 : Clock_1Hz -- Gives two clock divisions.
PORT MAP ( SYS_CLK, RESET,CLK256HZ, CLK1HZ);
C2 : Array_Count -- Initialize array with some numbers on every 1Hz edge
PORT MAP ( CLK1HZ, RESET, my_digit);
C3 : Display_Driver -- Dispaly the numbers on seven segments with 256Hz switching time between segments.
PORT MAP (RESET , CLK256HZ, CLK1HZ, my_digit, SEG_CATHODES, AN_EN);
end Behavioral;
The code is synthesizable and works on BASYS2 board, However I cannot simulate it via a testbench.
--------------------My TestBench -------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use work.my_array_pkg.all;
ENTITY pkg_tb IS
END pkg_tb;
ARCHITECTURE behavior OF pkg_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT pkt_top
PORT(
sys_clk : IN std_logic;
RESET : IN std_logic;
AN_EN : OUT std_logic_vector(3 downto 0);
array_test : INOUT my_array;
Seg_Cathodes : OUT std_logic_vector(6 downto 0)
);
END COMPONENT;
--Inputs
signal sys_clk : std_logic := '0';
signal RESET : std_logic := '0';
signal my_digit : my_array;
--Outputs
signal AN_EN : std_logic_vector(3 downto 0);
signal Seg_Cathodes : std_logic_vector(6 downto 0);
-- Clock period definitions
constant sys_clk_period : time := 20 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: pkt_top PORT MAP (
sys_clk => sys_clk,
RESET => RESET,
AN_EN => AN_EN,
array_test => my_digit,
Seg_Cathodes => Seg_Cathodes
);
-- Clock process definitions
sys_clk_process :process
begin
sys_clk <= '0';
wait for sys_clk_period/2;
sys_clk <= '1';
wait for sys_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';
-- insert stimulus here
wait;
end process;
END;
---------------------------------------------------------------
When simulate the ISIM gives an error about the 'array_test' not being availabe in the Top entity, and if this is removed the simulation remains blank.
Any Help about the testbench please.
I can't see a port named "array_test"in the description of the entity pkt_top. You must declare it an an output port in pkt_top.
Another way to avoid errors in testbench is to delete the .vhd file of testbench and create a new one for the entity you want to simulate.
In addition to, every time you edit the port of your top entity, you can delete the old and create a new testbench or edit the component of the same entity in your testbench.

How to connect GPIO in micro-controller?

How to connect 8-bit GPIO "General-Purpose Input/Output" with 3 8-bit timers (Timer0, Timer1, PWM) as multiplexer.
GPIO get the 3 Timers outputs as an input, choose between them. It's output is one of the 3 inputs it had as a multiplexer?
How can I make this connection in design also in VHDL by coding?
What will be the functionality of each pin in GPIO?
Thanks.
*-- Assuming you have logic to produce the mux selects: mux_sel(1 downto 0) :*
C1: PROCESS (timer0, timer1, pwm, mux_sel) IS
BEGIN
CASE mux_sel IS
WHEN "00" => gpio_in <= timer0;
WHEN "01" => gpio_in <= timer1;
WHEN "10" => gpio_in <= pwm;
WHEN OTHERS => NULL;
END CASE;
END PROCESS C1;
-- Even simpler:
gpio_in <= timer0 WHEN mux_sel = "00" ELSE
timer1 WHEN mux_Sel = "01" ELSE
pwm;

Resources