|
|
  |
"Схемотехнические трюки для ПЛИСоводов", создание аналога "Алгоритмические трюки для программистов" |
|
|
|
Dec 6 2011, 14:18
|

МедвеД Инженер I
   
Группа: Свой
Сообщений: 816
Регистрация: 21-10-04
Пользователь №: 951

|
Цитата(stu @ Dec 6 2011, 22:41)  не нашел куда написать, а новой темы....... .На AHDL можно написать: Код ff[3..0]: dffe; ff.(d, ena, clk, q) = (Din[3..0], ena, clk_GN, iDin[3..0]); На SV никак в одну строчку не укоротить? Код DFFE ff_all[3:0] (.d(Din), .ena(ena), .clk(clk_GN), .q(iDin)); ключевыe слова поиска - verilog array of instanceпервое что нашёл http://dropzone.tamu.edu/~lwang/ee468/slides/lec03.pdf
--------------------
Cogito ergo sum
|
|
|
|
|
Dec 7 2011, 04:51
|
Знающий
   
Группа: Свой
Сообщений: 555
Регистрация: 14-10-09
Пользователь №: 52 939

|
У меня такая проблемка возникла. Есть 32х.р. счетчик, который никогда не останавливается: Код always_ff@(posedge adc_mclk_mux or negedge rst_i) begin 27,648 MHz if (!rst_i) counter<='0; else if (!TRIG3_stb && TRIG3_rg_n) counter<=32'd0; //start condition else counter<=counter+1'b1; end На другой стороне процессор с 16р шиной (clk~49 MHz ), который должен прочитать "грамотно" за два обращения текущее значение данного счетчика. Понятное дело если его просто так читать, то получается полная каша. Ставлю защелку: Код always_ff@(negedge adc_mclk_mux or negedge rst_i) begin if (!rst_i) cnt_rg_HADC<='0; else if (!ff_hold) cnt_rg_HADC<=counter; end И, собственно, управление защелкой(LRD стоит 2 такта clk_i). Вначале читается старшее, потом младшее слово: Код always_ff@(posedge clk_i or negedge rst_i) begin if (!rst_i) fHold_value<='0; else if (!IOMS && !LRD) begin if (LA==pIOMS_ADC_CTRL_CNTR_L) fHold_value<='0; //LSB else if (LA==pIOMS_PXI_MUX_CNTR_H) fHold_value<='1; //MSB end end
always_ff@(negedge adc_mclk_mux or negedge rst_i) begin//posedge if (!rst_i) ff_hold<='0; else if ( fHold_value && IOMS) ff_hold<='1; else if (!fHold_value && IOMS) ff_hold<='0;
end при таком раскладе получается, что холдится только младшее слово. Итог:
В принципе устраивает. Но может как то грамотней можно сделать?
|
|
|
|
|
Dec 7 2011, 06:02
|

Местный
  
Группа: Свой
Сообщений: 235
Регистрация: 11-11-09
Пользователь №: 53 561

|
Цитата(Postoroniy_V @ Dec 6 2011, 17:18)  Код DFFE ff_all[3:0] (.d(Din), .ena(ena), .clk(clk_GN), .q(iDin)); У меня выдает Цитата Error (10253): Verilog HDL Module Instantiation error at tx_8b_10b.sv(82): cannot elaborate array of instances because the declaration for the instantiated module has not been analyzed не пойму, он дополнительно объявление требует или что?
--------------------
Мы ведь работаем, чтобы жить, а не живем, чтобы работать??? ;)
|
|
|
|
|
Dec 7 2011, 06:27
|
Местный
  
Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023

|
Цитата(stu @ Dec 7 2011, 09:02)  У меня выдает Error (10253): Verilog HDL Module Instantiation error at tx_8b_10b.sv(82): cannot elaborate array of instances because the declaration for the instantiated module has not been analyzed не пойму, он дополнительно объявление требует или что? Нужно сделать свой модуль - обёртку для DFFE, и его уже можно будет вставить сразу массивом. Например для LCELL: Код module lc(input in, output out); LCELL l (.in(in), .out(out)); endmodule и потом Код wire [7:0] p, q; lc lcq[7:0] (p, q); Для DFFE нужно аналогично
|
|
|
|
|
Dec 7 2011, 06:36
|

Местный
  
Группа: Свой
Сообщений: 235
Регистрация: 11-11-09
Пользователь №: 53 561

|
2 sazh & maksimp такие методы я понимаю. но это о5 многа букав. хотел в одну строку. как в http://electronix.ru/redirect.php?http://d...lides/lec03.pdfхотя код ниже приемлим =) Код always_ff @ (posedge clk) if (ena) iDin <= Din;
Сообщение отредактировал stu - Dec 7 2011, 06:50
--------------------
Мы ведь работаем, чтобы жить, а не живем, чтобы работать??? ;)
|
|
|
|
|
Dec 8 2011, 06:21
|
Местный
  
Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023

|
Цитата(Egor-ka @ Dec 7 2011, 16:08)  формирование импульсов с точность меньше периода макс. тактовой частоты с помощью линии задержки. Сейчас пытаюсь сделать задержку сигнала с точностью меньше периода, в симуляторе получается, а в железе нет, хотя уже замучился вручную ячейки расставлять и времена распространения сигналов подбирать. Посмотрите здесь http://www.alteraforum.com/forum/showthrea...2133&page=2и там по ссылкам. А вообще искать "delay" на alteraforum.com .
|
|
|
|
|
Dec 8 2011, 07:25
|
Участник

Группа: Участник
Сообщений: 36
Регистрация: 9-10-07
Пользователь №: 31 202

|
Цитата(maksimp @ Dec 8 2011, 10:21)  Посмотрите здесь http://www.alteraforum.com/forum/showthrea...2133&page=2и там по ссылкам. А вообще искать "delay" на alteraforum.com . Спасибо, изучаю. Думал, может, кто-то из отечественных плисоводов это делал...
|
|
|
|
|
Feb 24 2012, 12:02
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Вот решил написать свой вариант FIFO-буфера, правда я его в кристалле не тестировал. Прошу покритиковать. CODE library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all;
entity FIFO is generic (Addr_Size : natural := 3; -- Разрядность адреса (глубина FIFO) Data_Size : natural := 32); -- Разрядность данных port (RST : in std_logic; -- Сброс CLK_WR : in std_logic; -- Тактовый сигнал для записи WE : in std_logic; -- Разрешение записи (Write Enable) Data_WR : in std_logic_vector(Data_Size - 1 downto 0); -- Данные, записываемые в буфер CLK_RD : in std_logic; -- Тактовый сигнал для чтения RE : in std_logic; -- Разрешение чтения (Read Enable) Data_RD : out std_logic_vector(Data_Size - 1 downto 0); -- Данные, читаемые из буфера Full : out std_logic; -- Флаг того, что буфер полон Empty : out std_logic); -- Флаг того, что буфер пуст end entity FIFO;
architecture RTL of FIFO is
type FIFO_RAM_Type is array (0 to 2**Addr_Size - 1) of std_logic_vector(Data_Size - 1 downto 0); signal FIFO_RAM : FIFO_RAM_Type;
--================================================================================ ================================================-- -- Функция преобразования из двоичного кода в код Грея: -- --================================================================================ ================================================-- function Bin_to_Gray (D: unsigned) return unsigned is variable Q : unsigned(D'range); begin Q := ('0' & D(D'high downto 1)) xor D; return Q; end function Bin_to_Gray; --================================================================================ ================================================-- --================================================================================ ================================================-- -- Функция преобразования кода Грея в двоичный код: -- --================================================================================ ================================================-- function Gray_to_Bin (D: in unsigned) return unsigned is variable Q: unsigned(D'high downto D'low); begin Q(D'high) := D(D'high); for i in D'high - 1 downto D'low loop Q(i) := D(i) xor Q(i + 1); end loop; return Q; end function; --================================================================================ ================================================-- signal Addr_Write_Gray : unsigned(Addr_Size downto 0); -- Адрес записи данных в буфер в коде Грея signal Addr_Write_Gray_Next : unsigned(Addr_Size downto 0); -- Следующий адрес записи данных в буфер в коде Грея signal Addr_Read_Gray : unsigned(Addr_Size downto 0); -- Адрес чтения данных из буфера в коде Грея signal Addr_Write_Bin : unsigned(Addr_Size downto 0); -- Адрес записи данных в буфер в двоичном коде signal Addr_Write_Bin_Next : unsigned(Addr_Size downto 0); -- Следующий адрес записи данных в буфер в двоичном коде signal Addr_Read_Bin : unsigned(Addr_Size downto 0); -- Адрес чтения данных из буфера в двоичном коде signal WE_Allow : std_logic; -- Разрешение записи данных в FIFO-буфер signal RE_Allow : std_logic; -- Разрешение чтения данных из FIFO-буфера signal Full_Match : std_logic; -- Сравнение адресов записи и чтения для флага того, что буфер полон signal Empty_Match : std_logic; -- Сравнение адресов записи и чтения для флага того, что буфер пуст begin -- Адрес записи данных в буфер в двоичном коде: -- process(RST, CLK_WR) begin if (RST = '1') then Addr_Write_Bin <= (others => '0'); elsif (Rising_Edge(CLK_WR)) then if(WE_Allow = '1') then Addr_Write_Bin <= Addr_Write_Bin + 1; end if; end if; end process; -- Следующий адрес записи данных в буфер в двоичном коде: -- process(RST, CLK_WR) begin if (RST = '1') then Addr_Write_Bin_Next <= TO_UNSIGNED(1, Addr_Size + 1); elsif (Rising_Edge(CLK_WR)) then if(WE_Allow = '1') then Addr_Write_Bin_Next <= Addr_Write_Bin_Next + 1; end if; end if; end process; -- Адрес записи данных в FIFO-буфер в коде Грея: -- Addr_Write_Gray <= Bin_to_Gray(Addr_Write_Bin); -- Следующий адрес записи данных в буфер в коде Грея: -- Addr_Write_Gray_Next <= Bin_to_Gray(Addr_Write_Bin_Next); -- Адрес чтения данных из буфера в двоичном коде: -- process(RST, CLK_RD) begin if (RST = '1') then Addr_Read_Bin <= (others => '0'); elsif (Rising_Edge(CLK_RD)) then if(RE_Allow = '1') then Addr_Read_Bin <= Addr_Read_Bin + 1; end if; end if; end process; -- Адрес чтения данных из FIFO-буфера: -- Addr_Read_Gray <= Bin_to_Gray(Addr_Read_Bin); -- Запись данных в FIFO-буфер: -- process begin wait until (rising_edge(CLK_WR)); if(WE_Allow = '1') then FIFO_RAM(TO_INTEGER(Addr_Write_Gray(Addr_Size - 1 downto 0))) <= Data_WR; end if; end process; -- Чтение данных из FIFO-буфера: -- process begin wait until (rising_edge(CLK_RD)); if(RE_Allow = '1') then Data_RD <= FIFO_RAM(TO_INTEGER(Addr_Read_Gray(Addr_Size - 1 downto 0))); end if; end process; -- Разрешение записи данных в FIFO-буфер: -- WE_Allow <= '1' when (WE = '1' and Full_Match = '0') else '0'; -- Разрешение чтения данных из FIFO-буфера: -- RE_Allow <= '1' when (RE = '1' and Empty_Match = '0') else '0'; -- Сравнение адресов записи и чтения для флага того, что буфер полон: -- Full_Match <= '1' when (Addr_Write_Bin(Addr_Size - 1 downto 0) = Addr_Read_Bin(Addr_Size - 1 downto 0) and Addr_Write_Bin(Addr_Size) /= Addr_Read_Bin(Addr_Size) and (RE = '0' or (RE = '1' and WE = '1'))) else '0'; -- Флаг того, что буфер полон: -- Full <= '1' when (Full_Match = '1' or (Addr_Write_Bin_Next(Addr_Size - 1 downto 0) = Addr_Read_Bin(Addr_Size - 1 downto 0) and Addr_Write_Bin_Next(Addr_Size) /= Addr_Read_Bin(Addr_Size) and (RE = '0' and WE = '1'))) else '0'; -- Сравнение адресов записи и чтения для флага того, что буфер пуст: -- Empty_Match <= '1' when (Addr_Write_Bin = Addr_Read_Bin and (WE = '0' or (RE = '1' and WE = '1'))) else '0'; -- Флаг того, что буфер пуст: -- Empty <= Empty_Match; end architecture RTL;
Сообщение отредактировал ZED - Feb 24 2012, 12:04
Прикрепленные файлы
FIFO.rar ( 11.87 килобайт )
Кол-во скачиваний: 58
|
|
|
|
|
  |
5 чел. читают эту тему (гостей: 5, скрытых пользователей: 0)
Пользователей: 0
|
|
|