2013-11-13 2 views
-1

Итак, вот в чем проблема. Я написал код для двоичного разделителя, который должен выводить двоичный код 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; 

ответ

2

В основном я стреляю в темноту; возможно, если вы опубликуете имитационное изображение, это поможет нам лучше понять вашу проблему. Во всяком случае, так как мы в этом, почему бы не говорить о нескольких случайных вопросов:

  • код будет легче понять (и работать), если вы хотите разбить его на несколько блоков, каждый из с одной целью. Вы могли бы сделать один блок делением и вывести только фактор и остаток. Другой блок может принимать 8 значений BCD и мультиплексировать их так, чтобы они отображались правильно на дисплеях вашей платы. Если мы можем сосредоточиться на одной части проблемы за раз, вам будет легче обнаружить что-то не так.

  • Вы упомянули 3-битный выбор на ЖК-дисплее, но я не вижу в вашем коде, где вы его управляете. Может быть, вы должны вывести что-то на основе вашего сигнала MYcount?

  • Чтобы убедиться, что ваши функции работают нормально, вы можете разместить их в пакете и создать тестовый тест для самообслуживания. По крайней мере, так я и сделал бы это. Это вывело бы эту переменную из уравнения.

Пожалуйста, отправьте некоторые результаты моделирования, чтобы мы могли помочь вам.

+0

Спасибо, ты помог мне решить эту проблему! Я понял, что не управляю 3-битным выбором. Я создал новый процесс, который использовал переменную счетчика с нарастающими фронтовыми часами и оператором case для управления 3-битным выбором вывода. И с каждым соответствующим случаем соответствующий 7-сегментный 7-битный выход. –

 Смежные вопросы

  • Нет связанных вопросов^_^