|
Переворот матрицы |
|
|
|
Dec 27 2013, 13:07
|
Участник

Группа: Участник
Сообщений: 46
Регистрация: 26-02-13
Пользователь №: 75 801

|
Здравствуйте, уважаемые форумчане. Передо мною стоит задача потокового транспонирования матрицы. То есть есть матрица определенного размера, на вход которой последовательно поступают отсчеты. Накопил матрицу построчно, вычитал по столбцам. Написал код, его привожу дальше. Смысл его в том, что имеются два буфера. Сначала накапливаю данные в первый буфер. После накопления выставляю признак full. Начинаю читать из первого буфера, а приходящие данные записываю во второй буфер. После накопления второго буфера и одновременно вычитки первого "меняю их местами". Проверил в симуляторе - код работает. Просинтезировал, загрузил на реальном железе - на выходе тихо. Посмотрите, пожалуйста, может быть я в корне что-то делаю неправильно. Работаю с Xilinx ISE. Код library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.STD_LOGIC_ARITH.ALL;
entity matrix_transposition is generic ( N_ROWS : integer := 64; N_COLS : integer := 46 ); port ( clk : in std_logic; reset : in std_logic; din : in std_logic; din_valid : in std_logic; dout : out std_logic; dout_valid : out std_logic ; rd_addr_out : out integer ; rd_addr_v1_out : out integer ; rd_addr_v2_out : out integer ; wr_addr_out : out integer ; ready_out : out std_logic ); end matrix_transposition;
architecture RTL of matrix_transposition is constant SIZE : integer := N_ROWS * N_COLS; constant HI : integer := SIZE - 1; signal buf1 : std_logic_vector(HI downto 0); signal buf2 : std_logic_vector(HI downto 0); signal wr_addr : integer range 0 to HI := 0; signal rd_addr : integer range 0 to HI := 0; signal row_no : integer range 0 to N_ROWS-1 := 0; signal col_no : integer range 0 to N_COLS-1 := 0; signal buf_mux : std_logic := '0'; signal full : std_logic := '0'; begin
process(clk) begin if rising_edge(clk) then if din_valid = '1' then if buf_mux = '0' then buf1(wr_addr) <= din; else buf2(wr_addr) <= din; end if; if wr_addr = HI then wr_addr <= 0; else wr_addr <= wr_addr + 1; end if; if wr_addr = HI then buf_mux <= not(buf_mux); full <= '1'; end if; if row_no = N_ROWS-1 then row_no <= 0; if col_no = N_COLS-1 then col_no <= 0; else col_no <= col_no + 1; end if; else row_no <= row_no + 1; end if; if row_no = N_ROWS-1 then if col_no = N_COLS-1 then rd_addr <= 0; else rd_addr <= col_no + 1; end if; else rd_addr <= rd_addr + N_COLS; end if; end if; if buf_mux = '1' then dout <= buf1(rd_addr); else dout <= buf2(rd_addr); end if; dout_valid <= din_valid and full; end if; end process;
rd_addr_out <= rd_addr; -- rd_addr_v1_out <= rd_addr_v1; -- rd_addr_v2_out <= rd_addr_v2; wr_addr_out <= wr_addr; ready_out <= full;
end RTL;
|
|
|
|
|
 |
Ответов
(1 - 10)
|
Dec 27 2013, 13:57
|
Частый гость
 
Группа: Участник
Сообщений: 113
Регистрация: 12-03-07
Пользователь №: 26 075

|
Цитата(masverter @ Dec 27 2013, 17:07)  Просинтезировал, загрузил на реальном железе - на выходе тихо. Начнем с главного: что значит на выходе тихо? Типа все нули? Что синтезатор выдал на Ваши Код rd_addr_out : out integer ; rd_addr_v1_out : out integer ; rd_addr_v2_out : out integer ; wr_addr_out : out integer ?
|
|
|
|
|
Dec 27 2013, 15:58
|
Частый гость
 
Группа: Участник
Сообщений: 113
Регистрация: 12-03-07
Пользователь №: 26 075

|
У Вас чтение из буферов описано не совсем корректно. Попробуйте как-то так: Код ...
signal dout1 : std_logic; signal dout2 : std_logic; begin process(clk) begin if rising_edge(clk) then ... if buf_mux = '1' then dout1 <= buf1(rd_addr); else dout2 <= buf2(rd_addr); end if; ... end if; end process;
dout <= dout1 when buf_mux = '1' else dout2;
end RTL;
|
|
|
|
|
Dec 27 2013, 18:46
|
Участник

Группа: Участник
Сообщений: 46
Регистрация: 26-02-13
Пользователь №: 75 801

|
Цитата(olegras @ Dec 27 2013, 17:57)  Начнем с главного: что значит на выходе тихо? Типа все нули? Что синтезатор выдал на Ваши Код rd_addr_out : out integer ; rd_addr_v1_out : out integer ; rd_addr_v2_out : out integer ; wr_addr_out : out integer ? Читаю данные по rising_edge(clk) и dout_valid = '1'. Подразумеваю, что когда dout_valid все время в нуле - "на выходе тихо". Эти входы подключаю только в симуляторе: Код rd_addr_out : out integer ; rd_addr_v1_out : out integer ; rd_addr_v2_out : out integer ; wr_addr_out : out integer Цитата(olegras @ Dec 27 2013, 19:58)  У Вас чтение из буферов описано не совсем корректно. Если не трудно, скажите почему некорректно? Цитата(bogaev_roman @ Dec 27 2013, 18:13)  Для начала встроенным логическим анализатором посмотреть все управляющие сигналы. Если все правильно, то смотреть отчет на наличие временных ошибок при условии задания временных ограничений. Спасибо за совет, попробую в понедельник. Ошибок по времени в отчете нет. Вставлял код в изначально работающую обработку, где битики проходят через несколько блоков, затем пакуются и выкидываются в локальную сеть. Так же передаю данные в эти блоки по din_valid и читаю по dout_valid. Ну и работало, пока не добавил этот компонент. Вот и закралось сомнение, что ошибка в этом коде. Ну, наверно, где-то еще. Буду искать. Спасибо.
|
|
|
|
|
Dec 27 2013, 20:30
|
Местный
  
Группа: Участник
Сообщений: 230
Регистрация: 29-08-09
Пользователь №: 52 094

|
Цитата(masverter @ Dec 27 2013, 17:07)  Проверил в симуляторе - код работает. Просинтезировал, загрузил на реальном железе - на выходе тихо. Посмотрите, пожалуйста, может быть я в корне что-то делаю неправильно. Работаю с Xilinx ISE. Я в VHDL-е не очень копенгаген, но даже так видно, что сигнал reset ни к чему не прикладывается. На каком основании Вы считаете, что вся Ваша конструкция не свалится в хаос при начальных переходных процессах, типа устаканивания тактов на входе? Я за отсутствие принудительного сброса, который гарантированно приводит систему в начальное состояние бью инженеров по голове. Полной распечаткой стандарта verilog-а на мелованной бумаге формата А4.
Сообщение отредактировал o_khavin - Dec 27 2013, 20:33
|
|
|
|
|
Dec 28 2013, 04:57
|
Частый гость
 
Группа: Участник
Сообщений: 113
Регистрация: 12-03-07
Пользователь №: 26 075

|
Цитата(masverter @ Dec 27 2013, 21:46)  Читаю данные по rising_edge(clk) и dout_valid = '1'. Подразумеваю, что когда dout_valid все время в нуле - "на выходе тихо". Так значит у Вас dout_valid все время в нуле? Значит full не выставляется в единицу. Если Вы уверены что по din_valid подается единица - может быть что синтезатор Вас не правильно понял (результаты синтеза при Implementation и Simulation могут отличаться). Смотрите сигналы в чипскопе. Насчет корректности кода. Я Ваш код пропустил через свой синтезатор (у меня ISE 14.4). Сигналы buf1 и buf2 как двухпортовую память он видит, но просинтезировать их не может. Выдает фатальную ошибку. После небольших изменений в коде - по крайней мере синтез проходит нормально. Посмотрите как описывается однотактовое двухпортовое ОЗУ в Language Templates. Чтение из ОЗУ происходит вообще безусловно, в отдельный сигнал (в предложенном мною коде кстати условие при чтении из буферов все-таки надо убрать). То есть корректно сначала указать куда читать, а потом мультиплексировать. Тогда и Вы будете уверены, что синтезатор Вас понимает правильно.
Сообщение отредактировал olegras - Dec 28 2013, 05:03
|
|
|
|
|
Dec 28 2013, 09:57
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(masverter @ Dec 27 2013, 22:46)  Эти входы подключаю только в симуляторе: Код rd_addr_out : out integer ; rd_addr_v1_out : out integer ; rd_addr_v2_out : out integer ; wr_addr_out : out integer Если не трудно, скажите почему некорректно? Если часть проекта не "скармливается" синтезатору, а работает только в симуляторе, то на нее можно накладывать констрейн, выключающий синтез этого куска кода...
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Dec 28 2013, 10:30
|
Участник

Группа: Участник
Сообщений: 46
Регистрация: 26-02-13
Пользователь №: 75 801

|
Цитата(o_khavin @ Dec 28 2013, 00:30)  сигнал reset ни к чему не прикладывается. На каком основании Вы считаете, что вся Ваша конструкция не свалится в хаос при начальных переходных процессах, типа устаканивания тактов на входе? Провозился с этой проблемой всю пятницу - пробовал разные варианты. Как шаг отчаяния - отключил reset. Сейчас мне это кажется глупым... Цитата(olegras @ Dec 28 2013, 08:57)  Насчет корректности кода. Я Ваш код пропустил через свой синтезатор (у меня ISE 14.4). Сигналы buf1 и buf2 как двухпортовую память он видит, но просинтезировать их не может. Выдает фатальную ошибку. После небольших изменений в коде - по крайней мере синтез проходит нормально. Да, ISE не синтезирует мою схему. Извиняюсь, что вводил в заблуждение. Считал, что PlanAhead и ISE работают одинаково с точки зрения синтеза схем. PlanAhead синтезирует: HDL Synthesis Report Macro Statistics # RAMs : 2 2944x1-bit dual-port RAM : 2 # Adders/Subtractors : 4 12-bit adder : 2 6-bit adder : 1 7-bit adder : 1 # Registers : 8 1-bit register : 4 12-bit register : 2 6-bit register : 2 # Multiplexers : 3 1-bit 2-to-1 multiplexer : 1 12-bit 2-to-1 multiplexer : 1 7-bit 2-to-1 multiplexer : 1
|
|
|
|
|
Jan 14 2014, 05:50
|
Участник

Группа: Участник
Сообщений: 46
Регистрация: 26-02-13
Пользователь №: 75 801

|
Всем спасибо за помощь - проблема решилась. Работаю с ComBlock'ами, не поставил сжатие *.bit файла в настройках проекта и, как следствие, превысил допустимый размер. А случилось это как раз после добавления кода переворота матрицы - вот и грешил на этот компонент.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|