【发布时间】:2014-02-25 16:55:01
【问题描述】:
我正在用 VHDL 制作一个简单的井字游戏(计算机与用户),代码几乎完成了,但有些东西我不知道如何处理它。
总共有三个主要模块,基于当前网格的计算机移动,网格状态,由计算机或用户填充哪个单元格,一个从网格模块检索网格并处理这些组件的主模块以及用户的移动。
所以,在这个主模块中,我有一个组件将移动(通过计算机或用户)发送到网格模块,并在此主模块中更新其当前网格信号,然后是第二个组件(计算机移动)接受网格状态(即信号)并据此采取行动。因此,这也需要发送到网格模块以进行更新。但是,当涉及到按此顺序运行时,这并没有真正起作用。
简而言之,我的问题是,我如何才能按照组件执行的顺序更新这个主信号,或者更一般地说,我如何让一个需要成为另一个输入的组件更新一个信号分别是组件?
感谢您的帮助。
编辑
这里是部分主模块代码
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);
这里是网格模块
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;
计算机实体移动模块
---------------------------------
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;
---------------------------------
所以,发生的情况是,信号 grid_status 应该首先由用户移动自动更新,然后当它更新时,它会通过管道传输到 compmove 模块,以便计算机决定填充哪个单元格。之后,grid_status 应该再次更新。另外,“1”是用户移动,“2”是计算机在网格中移动。
希望这能清除我所追求的。
(添加了来自link的图片)
编辑 2:
感谢 David 和 fru1tbat 的帮助,我实际上可以让它工作了!原来我错过了让 compmove 对 grid_status 敏感。 但是,如果用户选择另一个单元格,现在它只适用于第一轮而不是第二轮。以下是更新后的代码:
主模块(当前状态)
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;
grid_ 模块
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;
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
它几乎就在那里,我相信 compmove 的敏感列表中的一个小改动可能会让它相应地检索更新的 grid_status ,因为目前在第一轮之后它不会接受更新的 grid_status 和comp_occupy 保持不变!
【问题讨论】:
-
很难理解你在问什么。如果可能的话,您是否认为您可以提供一张硬件图,注明有问题的信号以及一些相关声明?
-
好的,用更多信息更新了帖子。
-
恐怕我还是不太清楚你在问什么,我可以问你一张图表吗? (如果您试图将两个信号合并到一个输入中,则必须先合并这两个信号......例如或将它们合并在一起)
-
感谢您的回复!这有意义吗? link
-
您的实体/架构对当前的编写方式看起来像是他们保证
currentgrid是原子写入、接收的。它们将被一个增量周期分开。在不了解compmove的情况下,difficulty上的并发事件是否可能导致您的问题?当然,另一种可能性是您在某处出现错误(例如compmove)。
标签: components vhdl sequential