Итак, вот в чем проблема. Я написал код для двоичного разделителя, который должен выводить двоичный код 7-битного 7-сегментного дисплея, чтобы перейти на 8-сегментный сегментный дисплей. (2 7сегменты для дивиденда, делителя, частного, остатка каждого и в этом порядке). Этот 8 x 7сегментный дисплей на моем dev-board имеет один 7-битный вход (от a до g) и 3-битный. Итак, основная идея заключается в том, что я должен выводить дивиденды, делители, частное и остальное последовательно, непрерывно и достаточно быстро, так что для человеческого глаза результат выглядит постоянным, несмотря на то, что каждый из восьми 7 сегментов включается одним один в зависимости от того, что мой выход. Первоначально делитель дает все выходы (дивиденд, делитель, коэффициент, остаток) в двоичном формате, которые затем преобразуются функцией в 8-битный бит bcd, а затем номер bcd разбивается на два 4-битных номера bcd другой функцией (Теперь у меня есть 8 выходных переменных: 2 - дивиденд, 2 - делитель и т. Д.). Эти 4-битные числа преобразуются другой функцией в 7 сегментов.Выполнение секвенциальных записей в VHDL для синтеза
Вот полный код:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
entity division is
generic(SIZE: INTEGER := 8);
port(reset: in STD_LOGIC; --reset
en: in STD_LOGIC; --enable
clk: in STD_LOGIC; --clock
num: in STD_LOGIC_VECTOR((SIZE - 1) downto 0); --dividend
den: in STD_LOGIC_VECTOR((SIZE - 1) downto 0); --divisor
whatgoes:out STD_LOGIC_VECTOR(6 downto 0) --output
);
end division;
architecture behav of division is
signal bufreg: STD_LOGIC_VECTOR((2 * SIZE - 1) downto 0); --signal array to hold both accumulator and dividend registers as one i.e bufreg(18 bits)
signal dbuf: STD_LOGIC_VECTOR((SIZE - 1) downto 0); --signal array to hold the divisor
signal count: INTEGER range 0 to SIZE; --count to determine when to stop
signal MYcount: INTEGER range 0 to 100;
signal res: STD_LOGIC_VECTOR((SIZE - 1) downto 0); --result/quotient
signal rm : STD_LOGIC_VECTOR((SIZE - 1) downto 0); --remainder
alias ADreg is bufreg((2 * SIZE - 1) downto SIZE); --ADreg is is alias for top half of bufreg register(17th to 9th bit)
alias DVNDreg is bufreg((SIZE - 1) downto 0); --DVNDreg is is alias for bottom half of bufreg register(8th to 0th bit)
--Function definitions
function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector; --converts 8 bit binary to 8 bit BCD
function m7seg (bin : std_logic_vector(3 downto 0)) return std_logic_vector; --converts 4 bit BCD to 7 bit 7segment
function breakdown1 (bin : std_logic_vector(7 downto 0)) return std_logic_vector; --breaks an 8 bit BCD into a 4 bit BCD with lower bits
function breakdown2 (bin : std_logic_vector(7 downto 0)) return std_logic_vector; ----breaks an 8 bit BCD into a 4 bit BCD with higher bits
--this function assigns the first 4 bits of an 8 bit BCD number to a 4-bit vector
function breakdown1 (bin : std_logic_vector(7 downto 0)) return std_logic_vector is
variable bint : std_logic_vector(3 downto 0) :=bin(3 downto 0);
begin
return bint;
end breakdown1;
--this function assigns the last 4 bits of an 8 bit BCD number to a 4-bit vector
function breakdown2 (bin : std_logic_vector(7 downto 0)) return std_logic_vector is
variable bint : std_logic_vector(3 downto 0) :=bin(7 downto 4);
begin
return bint;
end breakdown2;
--This function converts 8 bit binary to 8 bit BCD
function to_bcd (bin : std_logic_vector(7 downto 0)) return std_logic_vector is
variable i : integer:=0;
variable bcd : std_logic_vector(7 downto 0) :=(others => '0');
variable bint : std_logic_vector(7 downto 0) :=bin;
variable bcd2 : std_logic_vector(7 downto 0) :=(others => '0');
begin
for i in 0 to 7 loop -- repeating 8 times.
bcd(7 downto 1) := bcd(6 downto 0); --shifting the bits.
bcd(0) := bint(7);
bint(7 downto 1) := bint(6 downto 0);
bint(0) :='0';
if(i < 7 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(3 downto 0) := bcd(3 downto 0) + "0011";
end if;
if(i < 7 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.
bcd(7 downto 4) := bcd(7 downto 4) + "0011";
end if;
--if(i < 7 and bcd(11 downto 8) > "0100") then --add 3 if BCD digit is greater than 4.
--bcd(11 downto 8) := bcd(11 downto 8) + "0011";
--end if;
end loop;
bcd2(7 downto 0):=bcd(7 downto 0);
return bcd2;
end to_bcd;
--This function converts 4 bit bcd to 7 segment
function m7seg (bin : std_logic_vector(3 downto 0))return std_logic_vector is
variable bint : std_logic_vector(3 downto 0):=bin(3 downto 0);
variable out7 : std_logic_vector(6 downto 0);
begin
case bint is
when "0000"=> out7:="1111110";
when "0001"=> out7:="0110000";
when "0010"=> out7:="1101101";
when "0011"=> out7:="1111001";
when "0100"=> out7:="0110011";
when "0101"=> out7:="1011011";
when "0110"=> out7:="X011111";
when "0111"=> out7:="1110000";
when "1000"=> out7:="1111111";
when "1001"=> out7:="111X011";
when others=> out7:="0000000";
end case;
return out7;
end m7seg;
begin
--our process begins here (shift and subtract/ Non restoring division)
p_001: process(reset, en, clk, bufreg)
begin
if reset = '1' then
res <= (others => '0');
rm <= (others => '0');
dbuf <= (others => '0');
bufreg <= (others => '0');
count <= 0;
MYcount <= 1;
elsif rising_edge(clk) then
if en = '1' then
case count is
when 0 =>
ADreg <= (others => '0');
DVNDreg <= num;
dbuf <= den;
res <= DVNDreg;
rm <= ADreg;
count <= count + 1;
when others =>
if bufreg((2 * SIZE - 2) downto (SIZE - 1)) >= dbuf then
ADreg <= '0' & (bufreg((2 * SIZE - 3) downto (SIZE - 1)) - dbuf((SIZE - 2) downto 0));
DVNDreg <= DVNDreg ((SIZE - 2) downto 0) & '1';
else
bufreg <= bufreg((2 * SIZE - 2) downto 0) & '0';
end if;
if count /= SIZE then
count <= count + 1;
else
count <= 0;
end if;
end case;
end if;
res <= DVNDreg;
rm <= ADreg;
MYcount<=MYcount+1;
whatgoes<=(others => '0');
case MYcount is
when 2 =>
whatgoes<=m7seg(breakdown1(to_bcd(rm))); --first 7segment(lower bits of remainder)
when 3 =>
whatgoes<=m7seg(breakdown2(to_bcd(rm))); --second 7segment (higher bits of remainder)
when 4 =>
whatgoes<=m7seg(breakdown1(to_bcd(res))); --third 7segment (lower bits of result/quotient)
when 5 =>
whatgoes<=m7seg(breakdown2(to_bcd(res))); --fourth 7segment (higher bits of result/quotient)
when 6 =>
whatgoes<=m7seg(breakdown1(to_bcd(den))); --fifth 7segment (lower bits of divisor)
when 7 =>
whatgoes<=m7seg(breakdown2(to_bcd(den))); --sixth 7segment (higher bits of divisor)
when 8 =>
whatgoes<=m7seg(breakdown1(to_bcd(num))); --seventh 7segment (lower bits of number/dividend)
when 9 =>
whatgoes<=m7seg(breakdown2(to_bcd(num))); --eigth 7segment (higher bits of number/dividend)
when 10 =>
MYcount<=1;
when others =>
NULL;
end case;
end if;
end process;
end behav;
Когда я пытаюсь запустить симуляции, это дает мне все виды фанки вещи. Я хочу, чтобы выход (whatgoes (6 downto 0)) изменился с нарастающим фронтом часов (clk). Проблема в том, что, поскольку я новичок в VHDL, у меня возникло множество проблем с синтезом последовательных операторов. Внутри процесса p_001 с включением, синхронизацией и сбросом в списке чувствительности я поставлю этот оператор case. Он выполняется при положительном краевом условии. Код экстракт:
case MYcount is
when 2 =>
whatgoes<=m7seg(breakdown1(to_bcd(rm))); --first 7segment(lower bits of remainder)
when 3 =>
whatgoes<=m7seg(breakdown2(to_bcd(rm))); --second 7segment (higher bits of remainder)
when 4 =>
whatgoes<=m7seg(breakdown1(to_bcd(res))); --third 7segment (lower bits of result/quotient)
when 5 =>
whatgoes<=m7seg(breakdown2(to_bcd(res))); --fourth 7segment (higher bits of result/quotient)
when 6 =>
whatgoes<=m7seg(breakdown1(to_bcd(den))); --fifth 7segment (lower bits of divisor)
when 7 =>
whatgoes<=m7seg(breakdown2(to_bcd(den))); --sixth 7segment (higher bits of divisor)
when 8 =>
whatgoes<=m7seg(breakdown1(to_bcd(num))); --seventh 7segment (lower bits of number/dividend)
when 9 =>
whatgoes<=m7seg(breakdown2(to_bcd(num))); --eigth 7segment (higher bits of number/dividend)
when 10 =>
MYcount<=1;
when others =>
NULL;
end case;
Я уверен, что моя проблема лежит здесь, так как остальная часть моего кода работает отлично. Приносим извинения, что вы загрузили такой запутанный беспорядок кода. Я искренне застрял, и я был на это очень много часов. Любая помощь будет принята с благодарностью. Я знаю, что для такой долгой, скучной и нубийской проблемы требуется особый вид преданности и терпения. Но тем, кто может помочь или предоставить ссылку на то, что имеет ответ на мою проблему, вы бы сделали мне отличный сервис.
Я использую ISE 14.3 и iSim.
Итак, благодаря Рику, я решил это. Он помог мне понять, что я забыл управлять 3-битным выбором вывода. Как оказалось, вождение с использованием оператора case и переменной подсчета помогло решить мою проблему выполнения кода последовательно. Я знаю, что код не точно написан организованным способом, но я надеюсь, что со временем я поправится.
process (clk,tmp,rm,res,den,num)
variable CLR: boolean:=true;
begin
if (CLR=true) then
tmp <= "000";
CLR:=false;
elsif (clk'event and clk='1') then
tmp <= tmp + 1;
if tmp<=8 then
CLR:=true;
end if;
end if;
case tmp is
when "000" =>
whatgoes<=m7seg(breakdown1(to_bcd(rm))); --first 7segment(lower bits of remainder)
when "001" =>
whatgoes<=m7seg(breakdown2(to_bcd(rm))); --second 7segment (higher bits of remainder)
when "010" =>
whatgoes<=m7seg(breakdown1(to_bcd(res))); --third 7segment (lower bits of result/quotient)
when "011" =>
whatgoes<=m7seg(breakdown2(to_bcd(res))); --fourth 7segment (higher bits of result/quotient)
when "100" =>
whatgoes<=m7seg(breakdown1(to_bcd(den))); --fifth 7segment (lower bits of divisor)
when "101" =>
whatgoes<=m7seg(breakdown2(to_bcd(den))); --sixth 7segment (higher bits of divisor)
when "110" =>
whatgoes<=m7seg(breakdown1(to_bcd(num))); --seventh 7segment (lower bits of number/dividend)
when "111" =>
whatgoes<=m7seg(breakdown2(to_bcd(num))); --eigth 7segment (higher bits of number/dividend)
when others =>
NULL;
end case;
sel<=tmp;
end process;
Спасибо, ты помог мне решить эту проблему! Я понял, что не управляю 3-битным выбором. Я создал новый процесс, который использовал переменную счетчика с нарастающими фронтовыми часами и оператором case для управления 3-битным выбором вывода. И с каждым соответствующим случаем соответствующий 7-сегментный 7-битный выход. –