VHDL Программный счетчик, использующий сигналы и ранее сделанные компоненты?
Я в настоящее время нахожусь в середине проекта, где я пытаюсь разработать процессор с одним циклом. Я делаю это без какой-либо облицовки, так как это значительно усложнит дизайн. Я просто делаю шаги ребенка, когда узнаю это. Я застрял в этой части, где я просто пытаюсь кодировать счетчик программ (ПК), используя ранее сделанные компоненты.
Модель моего дизайна выглядит вот так вот. Извините, не знаю, почему он вышел темным, но если вы нажмете на него, он будет отображаться правильно. ПК и theMUX являются 32-битными компонентами, поэтому я предполагаю, что сумматор тоже.
Вот код, который мне дали, моя реализация начинается с оператора begin в строке 41. Пока не обращайте на это внимания, это просто случайная тарабарщина, которую я пытался.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
---------------------------------------------------
entity pc_update is
port( clk: in std_logic; -- clock
incH_ldL: in std_logic; -- increment PC = PC + 4 when high,
-- load PCInput when low
PCInput: in std_logic_vector(31 downto 0); -- external input for PC
InstrAddr: out std_logic_vector(31 downto 0) ); -- instruction address
end entity pc_update;
----------------------------------------------------
architecture pc_update_arch of pc_update is
component register32 is
port( clr: in std_logic; -- async. clear
clk: in std_logic; -- clock
ld: in std_logic; -- load
D: in std_logic_vector(31 downto 0); -- data input
Q: out std_logic_vector(31 downto 0) ); -- data output
end component register32;
component mux2to1_32 is
port( sel: in std_logic; -- selection bit input
X0: in std_logic_vector(31 downto 0); -- first input
X1: in std_logic_vector(31 downto 0); -- second input
Y: out std_logic_vector(31 downto 0)); -- output
end component mux2to1_32;
signal PC_current: std_logic_vector(31 downto 0); -- the current state of PC reg
signal PC_add_4: std_logic_vector(31 downto 0); -- output from the adder
signal PC_next: std_logic_vector(31 downto 0); -- output from the MUX
begin
PC: register32 Port Map(
clk, Q, clr, D);
MUX: mux2to1_32 Port Map(
X0,sel,X1,Y);
process (incH_ldL)
begin
wait until (clk = '1');
if incH_1dL = '0' then
InstrAddr <= X0;
else InstrAddr <= X1;
end if;
end process;
end architecture pc_update_arch;
Я довольно новичок в этом, поэтому у меня есть только слабое представление о том, как работают сигналы, и я не знаю, как я должен внедрять компоненты в дизайн. Я также смущен, что меня не попросили построить сумматор заранее. Теперь необходимо использовать его как компонент, который я угадываю?
Во всяком случае, я пробовал разные вещи, которые наткнулись на поиск, такие как отображение портов, которое вы видите. Но я всегда получаю какую-то ошибку, в настоящее время я получаю ошибку о том, что объекты Q, clr и D используются, но не объявлены. Как мне их объявить? Если я избавлюсь от этих утверждений, ошибка просто повторяется для объектов X0, X1 и Y. Любая помощь в правильном направлении будет принята с благодарностью. Спасибо, парни!
Кроме того, на всякий случай, если они вам нужны, регистр
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------------------------
entity register32 is port(
clr: in std_logic; -- async. clear
clk: in std_logic; -- clock
ld: in std_logic; -- load
D: in std_logic_vector(31 downto 0); -- data input
Q: out std_logic_vector(31 downto 0) ); -- data output
end entity register32;
----------------------------------------------------
architecture register32_arch of register32 is
begin
process(clk, clr)
begin
if clr = '1' then
q <= x"00000000";
elsif rising_edge(clk) then
if ld = '1' then
q <= d;
end if;
end if;
end process;
END register32_arch;
и MUX
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------------------------
entity mux2to1_32 is
port( sel: in std_logic; -- selection bit input
X0: in std_logic_vector(31 downto 0); -- first input
X1: in std_logic_vector(31 downto 0); -- second input
Y: out std_logic_vector(31 downto 0)); -- output
end entity mux2to1_32;
----------------------------------------------------
architecture mux2to1_32_arch of mux2to1_32 is
begin
Y <= X1 when (SEL = '1') else X0;
end architecture mux2to1_32_arch;
РЕДАКТИРОВАТЬ Ладно, понятия не имею, правильно ли я это сделал, но я переписал portmaps. У меня были ошибки имен портов (sel, clk, X0, X1..etc), которые использовались, но не были инициализированы. Вот почему clr, clk и ld имеют начальные значения. Еще раз, не знаю, правильно ли это, но из-за этого ошибки исчезли. Я также понял, что никогда не добавлял VHDL-файлы register32 и mux2to1_32 в свой проект и после этого избавился от других ошибок, которые у меня были.
Таким образом, код компилируется, я включил в проект файл симуляции VWF для тестирования, но я ЗНАЮ, что результаты будут неверными.
Я пока не знаю всего, что не так, но я знаю, что мне нужно что-то сделать с PC_add_4. Это значение должно быть в основном (PC_current + 4), но я не уверен, как это сделать.
Вот обновленная часть кода (все остальное тоже самое)
PC: register32 Port Map(
clr => '0',
clk => '0',
ld => '1',
Q => PC_current,
D => PC_next
);
MUX: mux2to1_32 Port Map(
sel => incH_ldL,
X0 => PCInput ,
X1 => PC_add_4,
Y => PC_next
);
process (incH_ldL)
begin
if (rising_edge(clk)) then
if incH_ldL = '0' then
InstrAddr <= PC_current;
else InstrAddr <= PC_add_4;
end if;
end if;
end process;
И, в случае, если они помогают, мой список ошибок... я предполагаю, что ошибки, связанные с булавкой, - то, потому что у меня нет никаких аппаратных назначений, сделанных еще.
Предупреждение (10541): предупреждение объявления сигнала VHDL в pc_update.vhd(38): использовалось неявное значение по умолчанию для сигнала "PC_add_4", поскольку сигналу никогда не назначалось значение или явное значение по умолчанию. Использование неявного значения по умолчанию может привести к непреднамеренной оптимизации проекта.
Предупреждение (10492): предупреждение оператора процесса VHDL в pc_update.vhd(61): сигнал "clk" считывается внутри оператора процесса, но отсутствует в списке чувствительности оператора процесса
Предупреждение: выходные контакты застряли на VCC или GND
Предупреждение: конструкция содержит 34 входных контакта (ов), которые не управляют логикой
Предупреждение: Найдено 32 выходных контакта без назначения емкости нагрузки выходного контакта
Предупреждение. Параметр "Резервировать все неиспользуемые контакты" не был указан, и по умолчанию будет установлено значение "В качестве выходной площадки".
Предупреждение: не удается сгенерировать программные файлы, потому что вы используете программное обеспечение Quartus II в режиме оценки.
Предупреждение: не найдены пути для анализа времени
Критическое предупреждение: Нет точного назначения местоположения выводов для 66 выводов из общего количества выводов 66
ВТОРОЕ РЕДАКТИРОВАНИЕ Так что да, я исправил свой код, добавив PC_add_4 <= (PC_current + 4); после сопоставления портов и добавления "clk" в список чувствительности процесса. Тем не менее, я считаю, что мои осциллограммы в моделировании все еще неправильны, как показано здесь.
Похоже, что он рассматривает incH_lDL как чистый сигнал, а не просто передает PCInput в InstrAddr. Скорее всего, это связано с тем, что я установил значение по умолчанию "0" на карте портов. Я сделал это раньше, потому что это давало мне "использованные, но не объявленные" ошибки. Я постараюсь возиться с этим и опубликовать мои выводы.
Третье редактирование
Я отредактировал свой код как таковой:
process (incH_ldL, clk)
begin
if rising_edge(clk) then
if (incH_ldL = '0') then
InstrAddr <= PCInput ;
else InstrAddr <= PC_add_4;
end if;
end if;
end process;
Теперь моя симуляция показывает, что когда incH_lDL = 0, PCInput загружается в InstrAddr, однако, когда incH_lDL = 1, он просто загружает значение '4' и не увеличивает в начале каждого тактового цикла, как это должно быть... I нужно использовать PC_current, но я не уверен, как.... sicne вы не можете назначить один сигнал другому, как "PC_current <= PCInput". Я попробую еще кое-что, тем временем, любые указатели будут с благодарностью.
ЧЕТВЕРТАЯ РЕДАКТИРОВКА Спасибо всем, кто все еще читает это и проходит через все чтение.
Я пытался использовать PC_next и PC_current в моей реализации, но натолкнулся на "несколько константных драйверов для сетевых ошибок"PC_next".
МОЙ код процесса:
process (incH_ldL, clk, PC_next, PC_current)
begin
if rising_edge(clk) then
if (incH_ldL = '0') then
PC_next <= PCInput;
else PC_next <= PC_add_4;
end if;
end if;
InstrAddr <= PC_current;
end process;
Я знаю, что эта ошибка возникает, когда эти назначения выполняются внутри циклов? Я действительно в недоумении, что попробовать дальше.
1 ответ
Ваши карты портов в первом коде должны быть перенесены на сигналы. Вы размещаете имена портов компонентов в карте портов, что неверно. То, что вы хотели бы сделать, это создать сигналы, которые могут соединить эти компоненты, и вместо этого поместить их в поля карты портов (чтобы соответствовать соединениям на вашем изображении).