VHDL - using two components in a third entity - components

im pretty new in VHDL, and I have a simple question. I have a MAC (Multiply-And-Accumulate) entity which has 2 components in it: 'multiplier' and 'add_sub_n'. i want the MAC to get two inputs a,b, multiply them and add them to an older result when I used the Mac before. here is my code:
-- libraries decleration
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity MAC is
port (a : in std_logic_vector(N-1 downto 0);
b : in std_logic_vector(N-1 downto 0);
mac : in std_logic_vector(N-1 downto 0);
s : out std_logic_vector(N-1 downto 0);
end MAC;
architecture MAC_Logic of MAC is
component Multiplier is
port(
a,b : in std_logic_vector(N-1 downto 0);
c : out std_logic_vector(N-1 downto 0));
end component;
component Add_Sub_N is
port(
a,b : in std_logic_vector(N-1 downto 0);
sub : in std_logic;
cout : out std_logic;
s : out std_logic_vector(N-1 downto 0));
end component;
signal temp1 : std_logic;
begin
mul : Multiplier
port map(a=>a, b=>b, c=>temp1);
addsub : Add_Sub_N
port map(a=>temp1, b=>mac, sub=>0, cout=>cout, s=>s);
end MAC_Logic;
Im pretty stuck. if someone can please help I would appreciate it. thanks!

You have the following operations to perform:
m = a * b
acc' = m + acc
acc = acc'
Where acc' is the new value to store in the accumulator. Your code has entities for the multiply and add but nothing to describe the register that implements the accumulator. The accumulator register provides the second input to the adder. A control input will also be needed to enable writing to the accumulator only when a new product is available.

Related

How do I display the pulse width of a signal in vhdl?

I am trying to implement this code into a program that displays the pulse width of a signal onto the seven segment display on the basys2 board but when I download the code onto the board it just displays "0001" I figured out its just showing 1 from the part that does "x<=a_count_pw+1". It looks like it just adds 1 and thats it even when there is no signal being input.
I also get this warning "The signal is incomplete. The signal
does not drive any load pins in the design." This is supposed to be for my input signal? Here is my code. Any help is greatly appreciated thank you.
Top module: main_top - Behaviral(main_top.vhd)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity main_top is
port(
J3_IO1 : in std_logic;
mclk : in STD_LOGIC;
btn : in STD_LOGIC_VECTOR(3 downto 0);
a_to_g : out STD_LOGIC_VECTOR(6 downto 0);
an : out STD_LOGIC_VECTOR(3 downto 0);
dp : out STD_LOGIC
);
end main_top;
architecture Behaviral of main_top is
signal a_count_rst: STD_LOGIC;
signal a_count_pw: STD_LOGIC_VECTOR(15 downto 0);
signal a_count_pw_reported: STD_LOGIC_VECTOR(15 downto 0);
signal J3_IO1_q : STD_LOGIC;
signal J3_IO1_qq : STD_LOGIC;
component main
port(
x : in STD_LOGIC_VECTOR(15 downto 0);
clk : in STD_LOGIC;
clr : in STD_LOGIC;
a_to_g : out STD_LOGIC_VECTOR (6 downto 0);
an : out STD_LOGIC_VECTOR (3 downto 0);
dp : out STD_LOGIC
);
end component;
signal x: STD_LOGIC_VECTOR (15 downto 0);
begin
process(mclk)
if mclk'event and mclk='1' then
-- Synchronous process, clock edge is outer "if"
if a_count_rst='1' then --synchronous reset
a_count_pw <= b"0000000000000000";
a_count_pw_reported <= a_count_pw_reported;
else
J3_IO1_q <= J3_IO1; -- First D FF stage
J3_IO1_qq <= J3_IO1_q; -- Second D FF stage for edge detect
if J3_IO1_qq = '0' and J3_IO1_q = '1' then -- Detect rising edge
a_count_pw <= b"0000000000000000"; -- Start from 0 at rising edge
elsif J3_IO1_qq = '1' and J3_IO1_q = '0' then -- Detect falling edge
a_count_pw_reported <= a_count_pw; -- Capture count
else
x <= a_count_pw + 1;
end if;
end if;
end if;
end process;
X1 : main port map
(x=>x, clk=>mclk, clr=>btn(3), a_to_g=>a_to_g, an=>an, dp=>dp);
end Behaviral;
This is the next module for multiplexing the display.
Module: X1 - main - Behaviral (main.vhd)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity main is
port(
x : in STD_LOGIC_VECTOR(15 downto 0);
clk : in STD_LOGIC;
clr : in STD_LOGIC;
a_to_g : out STD_LOGIC_VECTOR (6 downto 0);
an : out STD_LOGIC_VECTOR (3 downto 0);
dp : out STD_LOGIC;
btn : in STD_LOGIC_VECTOR(3 downto 0);
J3_IO1 : in STD_LOGIC;
a_count_pw : in STD_LOGIC_VECTOR(15 downto 0)
);
end main;
architecture Behaviral of main is
signal s : STD_LOGIC_VECTOR (1 downto 0);
signal aen : STD_LOGIC_VECTOR (3 downto 0);
signal clkdiv : STD_LOGIC_VECTOR (20 downto 0);
signal digit : STD_LOGIC_VECTOR (3 downto 0);
begin
s <= clkdiv(18 downto 17);
aen <= "1111";
dp <= '1';
--4 to 1 multiplex
process(s, x)
begin
case s is
when "00" => digit <= x(3 downto 0);
when "01" => digit <= x(7 downto 4);
when "10" => digit <= x(11 downto 8);
when others => digit <= x(15 downto 12);
end case;
end process;
process(digit)
begin
case digit is
when X"0" => a_to_g <= "1000000"; --0
when X"1" => a_to_g <= "1111001"; --1
when X"2" => a_to_g <= "0100100"; --2
when X"3" => a_to_g <= "0110000"; --3
when X"4" => a_to_g <= "0011001"; --4
when X"5" => a_to_g <= "0010010"; --5
when X"6" => a_to_g <= "0000010"; --6
when X"7" => a_to_g <= "1011000"; --7
when X"8" => a_to_g <= "0000000"; --8
when X"9" => a_to_g <= "0010000"; --9
when X"A" => a_to_g <= "0001000"; --A
when X"B" => a_to_g <= "0000011"; --b
when X"C" => a_to_g <= "1000110"; --C
when X"D" => a_to_g <= "0100001"; --d
when X"E" => a_to_g <= "0000110"; --E
when others => a_to_g <= "0001110"; --F
end case;
end process;
--digit control
process(s, aen)
begin
an <= "1111";
if aen(conv_integer(s)) = '1' then
an(conv_integer(s)) <= '0';
end if;
end process;
--clock divider
process(clk, clr)
begin
if clr ='1' then
clkdiv <= (others => '0');
elsif clk'event and clk = '1' then
clkdiv <= clkdiv +1;
end if;
end process;
end Behaviral;
Here is my ucf file
ports.ucf
NET "mclk" LOC = "B8";
NET "a_to_g<0>" LOC = "L14";
NET "a_to_g<1>" LOC = "H12";
NET "a_to_g<2>" LOC = "N14";
NET "a_to_g<3>" LOC = "N11";
NET "a_to_g<4>" LOC = "P12";
NET "a_to_g<5>" LOC = "L13";
NET "a_to_g<6>" LOC = "M12";
NET "dp" LOC = "N13";
NET "an<3>" LOC = "K14";
NET "an<2>" LOC = "M13";
NET "an<1>" LOC = "J12";
NET "an<0>" LOC = "F12";
NET "btn<3>" LOC = "A7";
NET "J3_IO1" LOC = "J3";
As it looks to me, you haven't binded some port elements. I don't see x which you use as indicator for signal width. That also makes perfect sense if you look at the error - "The signal does not drive any load pins in the design". Elements from port should all be binded to actual pins. You could consider x as a 16 bits wide parallel interface where you read input values and later use them for your cause. As it looks to me, you could just use x as a signal or even variable and send back just actual bytes that you should write to seven segment display

divider of a 4 bit number

I wrote a vhdl code for divider that has 16 components in it and with nested loop but when synthesize it , it contains a specific errors in many lines .....
Any help is appreciated.
The following codes gives
ERROR:HDLParsers:851 -.vhd" Line 68. Formal cin of CAS with no default
value must be associated with an actual value
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity blockasli is
port ( divisor :std_logic_vector(3 downto 0);
dividend :in std_logic_vector(6 downto 0);
quotient :out std_logic_vector(3 downto 0);
remainder :out std_logic_vector(3 downto 0));
end blockasli;
architecture behavioral of blockasli is
-- component declaration ,specifies component interface
component CAS port( cin : in std_logic;
remainder_in : in std_logic;
T : in std_logic;
remainder_out : out std_logic;
cout : out std_logic;
divisor : in std_logic);
end component;
-- two arrays of four 4 bit vectors - the c and s and r linking signal between CAS
type reg_array is array (3 downto 0) of std_logic_vector(3 downto 0);
signal c, s: reg_array;
signal r : std_logic_vector (3 downto 0);
begin
GEN_CAS:
for row in 3 downto 0 generate
begin
GEN_CAS0:
for col in 3 downto 0 generate
begin
CAS_X : CAS port map(
cout => c(row)(col),divisor => divisor(col) , T => not r(row) );
define_remainder:if row=0 generate
begin
CAS_X : CAS port map(remainder_out=> remainder(col));
end generate define_remainder;
linkage_cin_with_c : if col>0 generate
begin
CAS_X : CAS port map( cin=> c(row)(col-1));
end generate linkage_cin_with_c ;
linkage_r_signal_with_cin: if col=0 generate
begin
CAS_X : CAS port map( cin => not r(row));
end generate linkage_r_signal_with_cin;
dividend_0_to_3 : if col=0 generate
begin
CAS_X : CAS port map( remainder_in => dividend(row));
end generate dividend_0_to_3 ;
dividend_4_to_6 : if row=3 generate
begin
CAS_X : CAS port map( remainder_in => dividend(col+3));
end generate dividend_4_to_6 ;
linkage_s_signal_with_remainder_in : if row<3 generate
begin
CAS_X : CAS port map( remainder_in => s(row)(col));
end generate linkage_s_signal_with_remainder_in;
linkage_s_signal_with_remainder_out: if col<3 and row>0 generate
begin
CAS_X : CAS port map( remainder_out => s(row-1)(col));
end generate linkage_s_signal_with_remainder_out;
linkage_r_signal_with_T: if row>0 and col=3 generate
begin
CAS_X : CAS port map( remainder_out => r(row-1));
end generate linkage_r_signal_with_T;
end generate GEN_CAS0;
quotient(row)<= not r(row);
end generate GEN_CAS;
end Behavioral;
You need to connect the cin port of the CAS module. It is defined in the component declaration, but is missing from some of your port maps.

VHDL using two components from a second file

I have a problem with my VHDL code, I use mypackage.VHD which contains all my components.
So here I have added USE WORK.mypackage.ALL; to use the necessary components for this part. This part uses 2 components, one of them gives me an error when I try to compile the file. If I include the 2 components exactly in the same format, I copy pasted the components from mypackage.VHD to this one and It worked, but once I delete them to use them from mypackage.VHD it gives me error.
I cant figure out what is the problem thank you very much in advanced for helping.
In short: I have 2 VHD file, mypackage.VHD,with my all my components and the second one (alu.VHD) that uses mypackage.VHD components with (USE WORK.mypackage.ALL;), looks like it cant identify the alu_1 components from mypackage.VHD. But dont know why.
Here is the error:
** Error (suppressible): C:/../alu_32.vhd(47): (vcom-1141) Identifier "alu_1" does not identify a component declaration.
The 2 components that my code uses:
alu_32 has no error, but alu_1 has an error when it tries to use it from mypackage.VHD.
COMPONENT alu_1
PORT (
a, b, c_in, less : IN STD_LOGIC;
ALUControl : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
c_out, result, set : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT alu_32
GENERIC (ALU_SIZE : INTEGER := 31); -- Il suffit de chager la valeur 31 a celle de la taille de lALU desiree!
PORT (
SrcA, SrcB : IN std_logic_vector(ALU_SIZE DOWNTO 0);
ALUControl : IN std_logic_vector (3 DOWNTO 0);
c_out : OUT std_logic;
Result : OUT std_logic_vector (ALU_SIZE DOWNTO 0);
zero : OUT std_logic
);
END COMPONENT;
My code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;
USE WORK.mypackage.ALL;
ENTITY alu_32_generic IS
GENERIC (ALU_SIZE : INTEGER := 31); -- Il suffit de chager la valeur 31 a celle de la taille de lALU desiree!
PORT (
SrcA, SrcB : IN STD_LOGIC_VECTOR (ALU_SIZE DOWNTO 0);
ALUControl : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
c_out : OUT STD_LOGIC;
result : OUT STD_LOGIC_VECTOR (ALU_SIZE DOWNTO 0);
zero : OUT std_logic
);
END alu_32_generic;
ARCHITECTURE alu_32 OF alu_32 IS
SIGNAL less_i : std_logic_vector (ALU_SIZE DOWNTO 0);
SIGNAL result_i : std_logic_vector (ALU_SIZE DOWNTO 0);
SIGNAL c_in_i : std_logic_vector (ALU_SIZE + 1 DOWNTO 0);
SIGNAL set : std_logic_vector (ALU_SIZE DOWNTO 0);
BEGIN
zero <= result_i(31) OR result_i(30);
GEN_REG : FOR i IN ALU_SIZE DOWNTO 0 GENERATE
alu_32 : alu_1
PORT MAP(
a => SrcA(i),
b => SrcB(i),
c_in => C_in_i(i),
ALUControl => ALUControl,
c_out => C_in_i(i + 1),
less => less_i(i),
set => set(i),
result => result_i(i)
);
END GENERATE GEN_REG;
c_in_i(0) <= ALUControl(2);
c_out <= C_in_i(ALU_SIZE + 1);
less_i(0) <= set(31);
less_i(ALU_SIZE DOWNTO 1) <= (OTHERS => '0');
result(ALU_SIZE DOWNTO 0) <= result_i;
END alu_32;
Without identifying which is line 47 (your example line counts don't match) you could note that for the entity alu_32_generic declaration:
ENTITY alu_32_generic IS
The architecture entity name:
ARCHITECTURE alu_32 OF alu_32 IS
doesn't match.
After correcting the entity name in the architecture declaration and commenting out the three use clauses not needed:
-- USE ieee.std_logic_arith.ALL;
-- USE ieee.std_logic_unsigned.ALL;
-- USE WORK.mypackage.ALL;
Your code then analyzes (which is what vcom does).
Note that if you enable the use clause more mypackage a declaration found as an architecture declarative item will supplant the one in the package. The use clause is not affecting your problem.
From verror:
vcom Message # 1141:
The syntax requires a component name. The name given does not denote a
component declaration.
You could note the two usages of alu_1 in your code appear valid. The closest to line 47 of your example appears on line 40 (second line below):
GEN_REG : FOR i IN ALU_SIZE DOWNTO 0 GENERATE
alu_32 : alu_1
You could also note the first occurrence is in the component declaration immediately within the architecture declaration:
ARCHITECTURE alu_32 OF alu_32 IS
COMPONENT alu_1
PORT (
Which raises the question as to whether or not you also have an entity declaration for alu_32 lurking around.
The moral of the story here is don't re-declare things you don't need to and get the entity name right in an architecture declaration.

How to run VHDL Components in a sequential fashion?

I'm making a simple TicTacToe game (computer vs user) in VHDL and the code is almost finished, but there is something that I can't figure out how to handle it.
Overall there are three main modules, computer move based on the current grid, grid status that takes in which cell to be filled either by computer or by user, a main module that retrieves the grid from the grid module and handle these components as well as the user move.
So, in this main module, I have a Component that sends the move (either by computer or user) to the grid module and in return updates its current grid Signal in this main module, then the second component (computer move) takes in the grid status (which is the Signal) and make a move based on that. Therefore, this also needs to get sent to the grid module for it to be updated. However, this doesn't really work in action when it comes to functioning in this order.
In a nutshell, my question is, how may I go about updating this main Signal in the order of the Components execution or more generally, how may I have a Signal be updated by a Component that needs to become the input of another Component respectively?
Thanks for your help.
Edit
Here is part of the main module code
ENTITY currentstate IS
PORT (to_occupy_cell : IN TO_SELECT; --user choice
start : IN STD_LOGIC; --initialize the grid
by_user : IN STD_LOGIC; --how to fill the grid (X or O)
difficulty : IN STD_LOGIC; --difficulty
winner_state : OUT INTEGER RANGE 0 to 2; --who is the winner?
currentgrid : OUT GRID (1 TO 3, 1 TO 3)); --outputs status of the grid after compmove to be displayed
END currentstate;
---------------------------------
ARCHITECTURE statearch OF currentstate IS
SIGNAL comp_occupy : TO_SELECT;
SIGNAL grid_status : GRID (1 TO 3, 1 TO 3);
COMPONENT grid IS -------saves the grid status
PORT (to_occupy_cell : IN TO_SELECT; start : IN STD_LOGIC; by_user : IN STD_LOGIC; currentgrid : OUT GRID (1 TO 3, 1 TO 3));
END COMPONENT;
COMPONENT compmove IS
PORT (current : IN GRID (1 TO 3, 1 TO 3); dif : IN STD_LOGIC; compsel : OUT TO_SELECT);
END COMPONENT;
BEGIN
U1: grid PORT MAP (to_occupy_cell, start, by_user ,grid_status);
U2: compmove PORT MAP (grid_status, difficulty, comp_occupy);
Here is the grid module
ENTITY grid IS
PORT (to_occupy_cell : IN TO_SELECT; --user choice
start : IN STD_LOGIC; --initialize the grid
by_user : IN STD_LOGIC; --how to fill the grid ( X or O)
currentgrid : OUT GRID (1 TO 3, 1 TO 3)); --outputs status of the grid after compmove to be displayed
END grid;
---------------------------------
ARCHITECTURE gridstatus OF grid IS
BEGIN
PROCESS (to_occupy_cell, start)
VARIABLE temp_grid : GRID (1 TO 3, 1 TO 3);
BEGIN
IF (start = '1' AND start'EVENT) THEN
temp_grid := (others => (others=>0));
END IF;
IF (by_user = '1') THEN
temp_grid(to_occupy_cell(0), to_occupy_cell(1)) := 1;
ELSIF (by_user = '0') THEN
temp_grid(to_occupy_cell(0), to_occupy_cell(1)) := 2;
END IF;
currentgrid <= temp_grid;
END PROCESS;
END gridstatus;
And entity of the computer move module
---------------------------------
ENTITY compmove IS
PORT(current : IN GRID (1 TO 3, 1 TO 3); --takes in the grid status
dif : IN STD_LOGIC; --difficulty
compsel : OUT TO_SELECT);
END compmove;
---------------------------------
So, what happens is that, the Signal grid_status should automatically be updated first by the user move and then when it is updated it gets piped into the compmove module for the computer to decide which cell to fill. Afterwards, the grid_status should get updated again. Also, '1' is the user move, '2' is the computer move in the grid.
Hope this clears what I'm after.
(image referenced from link added)
EDIT 2:
Thanks to the help of David and fru1tbat I could actually get it to work! Turns out I had missed making compmove sensitive to grid_status.
However, now it is only working for the first round but not the second round if the user selects another cell. Below are the updated codes:
Main module (currentstate)
ENTITY currentstate IS
PORT (to_occupy_cell : IN TO_SELECT; --user choice
start : IN STD_LOGIC; --initialize the grid
by_user : IN STD_LOGIC; --how to fill the grid ( X or O)
difficulty : IN STD_LOGIC; --difficulty
winner_state : OUT INTEGER RANGE 0 to 2); --who is the winner?
END currentstate;
---------------------------------
ARCHITECTURE statearch OF currentstate IS
SIGNAL occupy_to_grid : TO_SELECT;
SIGNAL comp_occupy : TO_SELECT;
SIGNAL user_move : STD_LOGIC;
SIGNAL grid_status : GRID (1 TO 3, 1 TO 3);
COMPONENT grid_ IS -------saves the grid status
PORT (to_occupy_cell : IN TO_SELECT; start : IN STD_LOGIC; by_user : IN STD_LOGIC; currentgrid : OUT GRID (1 TO 3, 1 TO 3));
END COMPONENT;
COMPONENT compmove IS
PORT (current : IN GRID (1 TO 3, 1 TO 3); by_user : IN STD_LOGIC; dif : IN STD_LOGIC; compsel : OUT TO_SELECT);
END COMPONENT;
BEGIN
U1: grid_ PORT MAP (occupy_to_grid, start, user_move,grid_status);
U2: compmove PORT MAP (grid_status, user_move, difficulty, comp_occupy);
PROCESS(comp_occupy, to_occupy_cell)
BEGIN
IF to_occupy_cell'EVENT THEN
occupy_to_grid <= to_occupy_cell;
user_move <= by_user;
END IF;
IF comp_occupy'EVENT THEN
occupy_to_grid <= comp_occupy;
user_move <= '0';
END IF;
END PROCESS;
END statearch;
The grid_ module
ENTITY grid_ IS
PORT (to_occupy_cell : IN TO_SELECT; --user choice
start : IN STD_LOGIC; --initialize the grid
by_user : IN STD_LOGIC; --how to fill the grid ( X or O)
currentgrid : OUT GRID (1 TO 3, 1 TO 3)); --outputs status of the grid after compmove to be displayed
END grid_;
---------------------------------
ARCHITECTURE gridstatus OF grid_ IS
BEGIN
PROCESS (to_occupy_cell, start)
VARIABLE temp_grid : GRID (1 TO 3, 1 TO 3);
BEGIN
IF (start = '1' AND start'EVENT) THEN
temp_grid := (others => (others=>0));
END IF;
IF (by_user = '1') THEN
temp_grid(to_occupy_cell(0), to_occupy_cell(1)) := 1;
ELSIF (by_user = '0') THEN
temp_grid(to_occupy_cell(0), to_occupy_cell(1)) := 2;
END IF;
currentgrid <= temp_grid;
END PROCESS;
END gridstatus;
Initial part of compmove
ENTITY compmove IS
PORT(current : IN GRID (1 TO 3, 1 TO 3); --takes in the grid status
by_user : IN STD_LOGIC; --to only gets triggered when user selects a cell
dif : IN STD_LOGIC; --difficulty
compsel : OUT TO_SELECT);
END compmove;
---------------------------------
ARCHITECTURE comparch OF compmove IS
BEGIN
PROCESS(by_user, current)
VARIABLE tempsel : TO_SELECT := (0,0);
VARIABLE occ_count : INTEGER := 0;
VARIABLE unocc : INTEGER := 0;
BEGIN
IF (dif = '0' AND current'EVENT AND by_user = '1') THEN
--------------bunch of codes here
It is almost there, I believe just a small change perhaps in the sensitivity list of compmove would do the trick for it to retrieve the updated grid_status correspondingly, because currently after the first round it doesn't take in the updated grid_status and comp_occupy remains unchanged!
You appear to be missing by_user from the process sensitivity list in grid:
process (to_occupy_cell, start) -- Add by_user to sensitivity list
variable temp_grid : grid (1 to 3, 1 to 3);
begin
if (start = '1' and start'event) then
temp_grid := (others => (others=>0));
end if;
if (by_user = '1') then
temp_grid(to_occupy_cell(0), to_occupy_cell(1)) := 1;
elsif (by_user = '0') then
temp_grid(to_occupy_cell(0), to_occupy_cell(1)) := 2;
end if;
currentgrid <= temp_grid;
end process;
The only thing that fit from your description was a missing event trigger the process. The idea being by_user isn't concurrent with any other input.
I also found a name conflict between grid in the component declaration in currentstate and the undeclared package containing the type declaration for type grid with two different VHDL analyzers. (After making up a package and type declarations for to_select and grid).
Addendum
I added a test bench, and also hooked up grid_status to the returned currentgrid in currentstate so it would show up at the top level.
library ieee;
use ieee.std_logic_1164.all;
use work.foobat.all;
entity test is
end entity;
architecture foo of test is
component currentstate is
port (
to_occupy_cell: in to_select; --user choice
start: in std_logic; --initialize the grid
by_user: in std_logic; --how to fill the grid (x or o)
difficulty: in std_logic; --difficulty
winner_state: out integer range 0 to 2; --who is the winner?
currentgrid: out grid (1 to 3, 1 to 3)
); --outputs status of the grid after compmove to be displayed
end component;
signal to_occupy_cell: to_select;
signal start: std_logic := '0';
signal by_user: std_logic := '1';
signal difficulty: std_logic := '0';
signal winner_state: integer range 0 to 2;
signal currentgrid: grid(1 to 3, 1 to 3);
begin
DUT:
currentstate
port map (
to_occupy_cell => to_occupy_cell,
start => start,
by_user => by_user,
difficulty => difficulty,
winner_state => winner_state,
currentgrid => currentgrid -- grid_status
);
STIMULUS:
process
begin
wait for 1 sec;
to_occupy_cell <= (2,2); -- center
start <= '1'; -- write 1 to gridstatus(2,2);
wait for 1 sec;
to_occupy_cell <= (1,1); -- corner
start <= '0'; -- no separate delta cycle event
wait for 1 sec;
wait;
end process;
end architecture;
So the two sets of grid values show below are grid_status (surfaced) and current on the compmove port. From what I can tell, grid_status gets to compmove.
This was done with ghdl and gtkwave. ghdl handles array signals in waveforms. The waveform trace image is larger than it will likely appear in your browser, you can open it in a separate tab/window or otherwise view it larger.
The values shown for the two versions grid_status/current appear identical.
Note there are three events on grid_status, the initial event which writes to leftmost row and column in the grid. I'm not sure why to_occupy_cell doesn't show up properly in the waveform, it doesn't show up as an array but does show the events. It's likely a result of how I declared the to_select type.
The initial or default transaction, the start'event and start = '1' transaction and to_occupy_cell transition (concurrent with start = 0).
Anyway, the point is that grid_status gets to compmove.
Your process that writes to the grid_status signal only accepts input from the user (comp_occupy doesn't connect to anything in your main module) so how can the computer update the grid with its move? What you seem to need is an input (or set of inputs) to the grid module that connects to comp_occupy, and a modified process in gridstatus which monitors both players and updates the grid from either source.
(edit)
On further consideration, I realize your intent may be to have a single input to the grid module which adds a move for either player. You appear to want to use events on by_user to update the grid, but I don't see the logic that switches by_user to create the sequence. You seem to need something like (in your main component):
process (to_occupy_cell, comp_occupy)
begin
if by_user = '1' then
occupy_to_grid <= to_occupy_grid;
else
occupy_to_grid <= comp_occupy;
end if;
by_user <= not by_user; -- on input from either source, alternate user for next input
end process;
Then map occupy_to_grid to grid instead of to_occupy_cell. This assumes that the new value of both 'occupy' signals is assigned on the same delta (or else by_user will flip back and forth unexpectedly), so if that's not the case, you will need to modify accordingly.
Let me know if this is close to what you're looking for.

VHDL - Scrolling Text on 7 segment Display

I am near to end in my project but stuck at some point. I can not resolve the problem
After deciding VHDL is having a hard time shifting indexes of arrays, I decided to change my shifter module. Now it is properly compiling and the RTL schematic seems true, but unfortunately I used a rather non-innovative way to shift the scancodes.
I defined an 64bit std_logic_vector that can hold up to 8 scancodes, and then parsed the 4 MSBmost bytes of this vector, and directed them to seven segment controller, that muxes the inputs and decides which seven segment will be enabled. I am thinking that I have problems with clock, but seeing nothing on the display makes me think some part of the device is malfunctioning. I am sure my keyboard controller works fine, as I tried it outindividually, shifter looks fine as well( I also tried this one on FPGA but without slowing the clock down, but nevertheless I was able to see the last scancode I entered), I haven't thought of any way/method to try out 7 segment controller, but that seems fine too. I don't know what the problem is, the text is not scrolling :(
Shifter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.numeric_std.all;
entity my_shifter is
port(clk : in std_logic;
Scan_Dav : in std_logic;
Data_in : in std_logic_vector (7 downto 0);
O1 : out std_logic_vector(7 downto 0);
O2 : out std_logic_vector(7 downto 0);
O3 : out std_logic_vector(7 downto 0);
O4 : out std_logic_vector(7 downto 0)
);
end my_shifter;
architecture bhv of my_shifter is
signal bytes : std_logic_vector(63 downto 0);
begin
process (clk) begin
if rising_edge(clk) then
if Scan_Dav = '1' then
bytes <= bytes (bytes'high-8 downto 0) & Data_in;
end if;
end if;
end process;
O1 <= bytes(63 downto 56);
O2 <= bytes(55 downto 48);
O3 <= bytes(47 downto 40);
O4 <= bytes(39 downto 32);
end bhv;
clkdivide.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity clkdivide is
Port (clkin: in std_logic;
clkout:out std_logic );
end clkdivide;
architecture Behavioral of clkdivide is
signal int_clock:std_logic;
begin
clkout<=int_clock;
process(clkin)
variable var:integer range 0 to 12500 :=0;
begin
if (clkin'event and clkin = '1') then
if var = 12500 then
int_clock <= not int_clock;
var:=0;
else
var:=var+1;
end if;
end if;
end process;
end Behavioral;
SevenSegmentControl.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
entity SevenSegmentController is
port (
CLK: in std_logic;
DEC1, DEC2, DEC3, DEC4: in std_logic_vector(7 downto 0);
SEGMENTS: out std_logic_vector(6 downto 0);
ANODES: out std_logic_vector(3 downto 0)
);
end SevenSegmentController;
architecture Behavioral of SevenSegmentController is
signal DecoderInput: std_logic_vector(7 downto 0);
signal CurrentDisplay: std_logic_vector(1 downto 0) := "00";
signal Prescaler: std_logic_vector(15 downto 0) := (others => '0');
begin
Multiplex: process(CLK)
begin
if rising_edge(CLK) then
if Prescaler(15) = '0' then
Prescaler <= Prescaler + 1;
else
CurrentDisplay <= CurrentDisplay + 1;
Prescaler <= (others => '0');
end if;
end if;
end process Multiplex;
SevenSegmentDecoder: entity work.SevenSegment_Decoder(Behavioral)
generic map ( INVERT_OUTPUT => '1' )
port map ( number => DecoderInput, segment => SEGMENTS );
DecoderInput <= DEC1 when CurrentDisplay = "00" else
DEC2 when CurrentDisplay = "01" else
DEC3 when CurrentDisplay = "10" else
DEC4 when CurrentDisplay = "11";
ANODES <= "0111" when CurrentDisplay = "00" else
"1011" when CurrentDisplay = "01" else
"1101" when CurrentDisplay = "10" else
"1110" when CurrentDisplay = "11";
end Behavioral;
We have no idea of the interface protocol of SevenSegment_Decoder, but it does look funny that you only have two inputs, but no clock. How does the decoder know when to interpret the signals?
"I haven't thought of any way/method to try out 7 segment controller"
Unless you are using a VERY old version of ISE, certainly older than ISE10, it has a fairly decent simulator (ISIM) built in. (ISIM goes back further than ISE10, but it wasn't really usable and even ISIM 10 had its problems...)
You would save a lot of time if you wrote a simple testbench and unit-tested these modules as you went along.

Resources