Plain 199 27 июня, 2020 Опубликовано 27 июня, 2020 · Жалоба always @(negedge SS) begin txbuf <= spitx; end always @(posedge SS) begin spirx <= spireg; end always @(negedge SCLK or posedge SS) begin if (SS) begin txld <= 1'b0; end else begin txld <= 1'b1; end end assign miso_mux = (~txld) ? txbuf[7] : spireg[7]; assign MISO = (~SS) ? miso_mux : 1'bz; always @(negedge SCLK) begin if (txld) begin spireg <= {spireg[6:0], MOSI}; end else begin spireg <= {txbuf[6:0], MOSI}; end end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 27 июня, 2020 Опубликовано 27 июня, 2020 (изменено) · Жалоба На этом форуме приводил задачку синтезируемого описания многопортового триггера (те с несколькими клоками), но ветку не нашел (емнип было в ~2010г). Изменено 27 июня, 2020 пользователем Leka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба module spi_slave( input i_core_clk, //FPGA clock input wire i_cs, input wire i_clk, input wire i_mosi, output reg o_miso, output reg o_irq, output reg [7:0]o_rx_buf, input wire [7:0]i_tx_buf ); //----------------------- MOSI ----------------------------- reg [2:0]counter_rx; reg [7:0]sr_rx; //Детектор flag_rx reg flag_rx, flag_rx_1, flag_rx_2; wire flag_rx_pos; assign flag_rx_pos = flag_rx_1 & ~flag_rx_2; always @(negedge i_core_clk) begin flag_rx_1 <= flag_rx; flag_rx_2 <= flag_rx_1; end always @(posedge i_clk or posedge i_cs) begin if(i_cs) counter_rx <= 3'd0; else begin counter_rx <= counter_rx + 1'd1; if(counter_rx == 3'd7) flag_rx <= 1'd1; else flag_rx <= 1'd0; sr_rx <= {sr_rx[6:0], i_mosi}; end end always @(posedge i_core_clk) begin if(flag_rx_pos) begin o_irq <= 1'd1; o_rx_buf <= sr_rx; end if(o_irq) o_irq <= 1'd0; end //-------------------------- MISO --------------------------------- reg [2:0]counter_tx; reg [7:0]sr_tx; reg miso_mux, f; always @(*) begin if(i_cs) o_miso = 1'bZ; else o_miso = miso_mux; if(f) miso_mux = sr_tx[7]; else miso_mux = i_tx_buf[7]; end always @(negedge i_clk or posedge i_cs) begin if(i_cs) begin f <= 1'd0; counter_tx <= 1'd0; end else begin f <= 1'd1; counter_tx <= counter_tx + 1'd1; if(!counter_tx && !f) sr_tx <= i_tx_buf << 1'd1; else if(counter_tx == 3'd7) sr_tx <= i_tx_buf; else sr_tx <= sr_tx << 1'd1; end end endmodule Что здесь не так? В симуляторе опять всё ОК! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба Асинхронный сброс придумали мазохисты. В разные точки ПЛИС клок и асинхронный сброс могут приходить в разными относительными задержками, это означает, что могут одновременно выполняться ветви "if" и "else". Одновременное выполнение ветвей "if" и "else" - возможный побочный эффект асинхронного дизайна, это надо учитывать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 28 июня, 2020 Опубликовано 28 июня, 2020 (изменено) · Жалоба Черновик, проверять лень. module spi_slave( input i_cs, input i_clk, input i_mosi, output o_miso, output reg [7:0] o_rx, input [7:0] i_tx ); reg p_cs, n_cs; reg [7:0] sr_rx, sr_tx; assign o_miso = i_cs ? 1'bz : n_cs ? i_tx[7] : sr_tx[7]; always @(posedge i_cs) begin o_rx <= sr_rx; end always @(posedge i_clk) begin p_cs <= i_cs; if(! i_cs) sr_rx <= {sr_rx, i_mosi}; end always @(negedge i_clk) begin n_cs <= p_cs; if(! p_cs) if(n_cs) sr_tx <= {i_tx, 1'b0}; else sr_tx <= {sr_tx, 1'b0}; end endmodule Изменено 28 июня, 2020 пользователем Leka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 199 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба Leka, это просто частный случай некоего последовательного интерфейса, а никакой не SPI, у которого один сдвиговый регистр, данные через который проходят транзитом в следующее устройство в цепочке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба Это м/б "SPI bus-compatible serial interface" (фраза из даташита на загрузочную флешку). Просто хотел привести вариант кода без асинхронных гонок для конкретной задачи. Для этого cs пропустил последовательно через "posedge i_clk" и "negedge i_clk". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 199 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба Добавил к предыдущему своему коду полутактовые буферы на MOSI и параллельную загрузку, теперь это железобетонный асинхронный SPI slave: always @(negedge SS) begin txbuf <= spitx; end always @(posedge SS) begin spirx <= spireg; end always @(negedge SCLK or posedge SS) begin if (SS) begin txsw <= 1'b0; end else begin txsw <= 1'b1; end end always @(posedge SCLK) begin txld <= txsw; mosibuf <= MOSI; end assign miso_mux = (~txsw) ? txbuf[7] : spireg[7]; assign MISO = (~SS) ? miso_mux : 1'bz; always @(negedge SCLK) begin if (txld) begin spireg <= {spireg[6:0], mosibuf}; end else begin spireg <= {txbuf[6:0], mosibuf}; end end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 28 июня, 2020 Опубликовано 28 июня, 2020 (изменено) · Жалоба Цитата Для этого cs пропустил последовательно через "posedge i_clk" и "negedge i_clk" Логика работы мне немного не подходит. Ваш вариант требует обязательного наличия сигналов i_clk во время высокого уровня i_cs. Загрузка в выходной буфер o_rx из sr_rx только при фронте i_cs, а не после принятия последнего бита. Изменено 28 июня, 2020 пользователем pinchemierda Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба Согласен, логика может не подходить. Но гарантировать отсутствие клока при высоком уровне cs можно только в случае одного устройства spi slave на шине. Надо разбираться, но сам всегда избегаю использования асинхронного сброса. Если устройство одно, и клок есть только при низком уровне cs, это сильно упрощает задачу, и д/б отражено в ТЗ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба Цитата теперь это железобетонный асинхронный SPI slave Протокол SPI slave подразумевает загрузку принятых данных только по фронту CS? И должно ли быть так, что всё что приходит от мастера возвращается по MISO следующим байтом (эхо)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба Счетчик бит лучше не использовать, если гарантировать нужное число тактов клока при низком cs. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба Просто если к примеру подчинённый один, то мастер будет всегда держать линию CS в нуле. Сигналов на линии CS вообще не будет почти никогда. Для любого устройства с SPI slave это не должно быть проблемой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 199 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба 2 минуты назад, pinchemierda сказал: Протокол SPI slave подразумевает загрузку принятых данных только по фронту CS? По стандарту, во время сеанса, принадлежность данных, проходящих транзитом сквозь соединённые в цепочку устройства, естественно не определена, лишь по его завершении. 7 минут назад, pinchemierda сказал: должно ли быть так, что всё что приходит от мастера возвращается по MISO следующим байтом (эхо)? По стандарту, мастер в сеансе выдаёт ровно столько тактов, сколько бит в сумме у всех сдвиговых регистров, соединённых в цепочку — соответственно, все одновременно загруженные в начале сеанса по единому SS и выдвинутые из устройств биты достаются мастеру, а выдвинутые из него — устройствам, которые получают их тоже одновременно по снятию единого SS. Таким образом, счётчик битов есть лишь у мастера, чтобы во время сеанса передавать и принимать байтами, словами и т.д., как ему удобнее. Устроить "эхо", выдавая больше тактов, чем количество бит в системе, т.е. тупо гонять данные по кругу, конечно можно, но бессмысленно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 0 28 июня, 2020 Опубликовано 28 июня, 2020 · Жалоба А нужна цепочка ТС? Если конечная задача - сделать spi мост между МК и конкретной схемой, не стоит усложнять. || соединение spi устройств с индивидуальными cs вроде чаще встречается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться