nopak 0 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба Написал очередь на верилоге. Ни как не могу понять почему она так себя ведёт. Почему были пропущены начальные данные. Результаты в присоединённой картинке. Помогите разобраться очередь module queue #( parameter N = 8, // разрядность данных count =16 ) ( input rst, input clk, input nextRead, input writeCMD, input reg [N-1:0] dataIn, output reg [N-1:0] dataOut ); reg [N-1:0] posRead; reg [N-1:0] posWrite; reg [N-1:0] state; reg [N-1:0] nextState; localparam RESET =0; localparam IDLE = 1; localparam WORK = 2; reg [N-1:0] data[count-1 : 0] ; //always @(posedge clk) always @* begin case (state) RESET: begin nextState = IDLE; posWrite = 0; posRead = 0; dataOut = 0; end IDLE: begin if (writeCMD) begin posRead = posWrite; nextState = WORK; data[posWrite] = dataIn; posWrite = posWrite + 1; end else begin end end WORK: begin if (writeCMD) begin nextState = WORK; data[posWrite] = dataIn; posWrite = posWrite + 1; end if (nextRead) begin dataOut = data[posRead]; posRead = posRead + 1; if (posRead == posWrite) nextState = IDLE; end end default: nextState = IDLE; endcase end always @(posedge rst or posedge clk) begin if (rst) state <= RESET; else state <= nextState; end endmodule тест module test_queue; localparam N = 8; localparam count =16; localparam cmdCount = 24; reg clk; reg reset; wire res; reg [3:0]rst_delay = 0; reg [8:0] cnt =0; reg writeCmd; reg readCmd; reg [N-1:0] data [count -1:0]; reg [N-1:0] writeData; wire [N-1:0] readData; reg [cmdCount -1 : 0] doWrite; reg [cmdCount -1 : 0] doRead; initial begin clk = 0; reset =0; data[0] = 1; data[1] = 2; data[2] = 3; data[3] = 4; data[4] = 5; data[5] = 6; data[6] = 7; data[7] = 8; data[8] = 101; data[9] = 3; data[10] = 6; data[11] = 55; data[12] = 3; data[13] = 2; data[14] = 0; data[15] = 1; doWrite = 24'b1101100111010011100; doRead = 24'b0010001101100111011; end always begin #10 clk = ~clk; end always @(posedge clk) begin rst_delay <= { rst_delay[2:0], 1'b1 }; doWrite[cmdCount -1 : 1] <= doWrite[cmdCount -2 : 0]; doRead[cmdCount -1 : 1] <= doRead[cmdCount -2 : 0]; writeCmd = doWrite[cmdCount -1]; readCmd = doRead[cmdCount -1]; writeData = data[cnt]; if (writeCmd) cnt = cnt + 1; end always @* reset = rst_delay[2]^rst_delay[3]; queue q(reset, clk, writeCmd, readCmd, writeData, readData); endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба Вот что странно. А почему сейчас в моде писать на HDL без единого комментария ? Я обычно через два - три месяца напрочь забываю почему было написано именно так. Спасает только бумага, на которой есть структурные схемы + коментарии помогают вспомнить... Неужели это только я страдаю пробелами в памяти ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nopak 0 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба Спешил. У моделсима странные отношения к русским буквам. Те в моделсиме нигде потом не видятся. А обычные (анси, утф8) в нём каракули. отмазка не ахти какая. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба module queue # ( parameter N = 8, // разрядность данных count = 16 ) ( input rst, input clk, input nextRead, input writeCMD, input reg [N - 1 : 0] dataIn, // Почему reg ? output reg [N - 1 : 0] dataOut ); localparam RESET = 0; localparam IDLE = 1; localparam WORK = 2; reg [N - 1 : 0] state; // Текущее состояние атомата reg [N - 1 : 0] nextState; // Следующее, вычисляемое состояние автомата reg [N - 1 : 0] posRead; reg [N - 1 : 0] posWrite; reg [N - 1 : 0] data[count - 1 : 0] ; always @ (posedge rst or posedge clk) begin if (rst) state <= RESET; else state <= nextState; end //always @(posedge clk) always @* begin case (state) RESET : begin //////////////////////////////////////////////////////////////////////////////// nextState = IDLE; posWrite = 0; posRead = 0; dataOut = 0; end IDLE : begin //////////////////////////////////////////////////////////////////////////////// if (writeCMD) begin // Пришла команда записи nextState = WORK; posRead = posWrite; // А что будет с сигналом posRead когда writeCMD = 0 ? Это LATCH... data[posWrite] = dataIn; // Типа должны записать данные в память. Вот только без клока это LATCH... posWrite = posWrite + 1; // Предполагается счетчик. Вот только это не счетчик... end else begin // Почему пусто ? end end WORK: begin //////////////////////////////////////////////////////////////////////////////// // Собственно тут та-же фигня: без клока одни латчи. if (writeCMD) begin nextState = WORK; data[posWrite] = dataIn; posWrite = posWrite + 1; end if (nextRead) begin dataOut = data[posRead]; posRead = posRead + 1; if (posRead == posWrite) nextState = IDLE; end end default : nextState = IDLE; endcase end endmodule Вообще в HDL спешить не стоит. Править и отлаживать баги дольше чем изначально сделать все правильно..... Слегка поковырял Ваш код. Код не для синтеза... Я бы для начала Вам посоветовал все счетчики и память описать отдельно. На начальном этапе освоения HDL лучше все не сваливать в кучу: автомат, память, счетчики, ибо новичку сложно представить в голове во что этот код выльется. Правильный подход: берете карандаш и листок бумаги и на ней рисуете структурную схему. А потом схему переносите на HDL. Вот когда научитесь понимать во что будет синтезироваться Ваш код, тогда пишите все в куче, главное чтобы было читаемо. P.S. Иногда ради читаемости кода приходится описывать автомат и счетчики в одной куче.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nopak 0 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба input reg [N - 1 : 0] dataIn, // Почему reg ? изначально было wire но тогда не передавались данные. dataIn всё время был в z. // А что будет с сигналом posRead когда writeCMD = 0 ? Это LATCH... Ну он не должен меняться. LATCH это страшно?. сильно плохо? posWrite = posWrite + 1; // Предполагается счетчик. Вот только это не счетчик... а что же тогда? и ведёт себя вроде бы логично // Собственно тут та-же фигня: без клока одни латчи. клок не поменял поведение модуля Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба 12 минут назад, nopak сказал: input reg [N - 1 : 0] dataIn, // Почему reg ? изначально было wire но тогда не передавались данные. dataIn всё время был в z. // А что будет с сигналом posRead когда writeCMD = 0 ? Это LATCH... Ну он не должен меняться. LATCH это страшно?. сильно плохо? posWrite = posWrite + 1; // Предполагается счетчик. Вот только это не счетчик... а что же тогда? и ведёт себя вроде бы логично // Собственно тут та-же фигня: без клока одни латчи. клок не поменял поведение модуля LATCH - это по сути комбинационная петля. Когда Вы с выхода комбинационной схемы сигнал подаете на вход этой же комбинационной схемы. В FPGA в 99,9% случаем LATCH - серьезная ошибка, ибо поведение латчей никак не контролируется синтезатором (Tsetup и Thold не определены для них), соответственно поведение Вашей схемы будет сильно зависеть от фазы луны, и положения солнца на горизонте.... Значит вооружаемся ручкой и бумагой и вспоминаем навыки рисования на бумаге Почему у многих такое упорное отрицание ручки и бумаги ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nopak 0 1 декабря, 2019 Опубликовано 1 декабря, 2019 · Жалоба наверное я что то не то нарисовал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 1 декабря, 2019 Опубликовано 1 декабря, 2019 · Жалоба 18 hours ago, Flip-fl0p said: Почему у многих такое упорное отрицание ручки и бумаги ? 1 hour ago, nopak said: наверное я что то не то нарисовал Часто проблема кроется не в том что нарисовал/не нарисовал. А в понимании как это синтезировать/интерпретировать. И посему действительно самое первое и главное правило - не лепить всё в кучу. Отдельно для каждого компонента, вплоть до регистров. А то когда оно всё скопом и вправду чепуха Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 15 1 декабря, 2019 Опубликовано 1 декабря, 2019 · Жалоба Старайтесь придерживаться общеупотребительной терминологии. FIFO, разумеется, очередь, но не сразу понятно, что имеется в виду. Сигналы интерфейса тоже желательно преименовать. Посмотрите, например, как они именуются в IP FIFO того вендора, с которым вы работаете. Конечный автомат (state machine) в FIFO не нужен. Одноклоковое FIFO вещь простая, КА там overdesign. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться