Jump to content

    

pinchemierda

Участник
  • Content Count

    74
  • Joined

  • Last visited

Community Reputation

0 Обычный

About pinchemierda

  • Rank
    Участник

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Оба работают пока. Просто тот, который не зависимый от системного клока (50 МГц) значительно шустрее. Сигнал o_irq добавил, который уже в домене системного клока. И даже работает всё! В общем вот последняя версия асинхронного SPI: module spi_slave( input wire i_core_clk, input wire SS, input wire SCLK, output wire MISO, input wire MOSI, output wire o_irq, output reg [7:0]spirx, input wire [7:0]spitx ); reg [7:0]txbuf; reg [7:0]spireg; reg txsw; reg [2:0]counter; always @(negedge SCLK or posedge SS) begin if(SS) begin txsw <= 1'b0; counter <= 3'd0; end else begin txsw <= 1'b1; counter <= counter + 1'd1; end end always @(negedge SCLK) begin if(counter == 3'd7) spirx <= spireg; if(counter == 3'd7 || ~txsw) txbuf <= spitx; end always @(posedge SCLK) begin spireg <= {spireg[6:0], MOSI}; end assign miso_mux = (txsw) ? txbuf[3'd7- counter] : spitx[3'd7-counter]; assign MISO = (~SS) ? miso_mux : 1'bz; //------------------------ o_irq ------------------------------------- reg q, q1, q2; assign o_irq = q1 & ~q2; always @(negedge SCLK) begin if(counter == 3'd7) q <= 1'd1; else q <= 1'd0; end //Синхронизация q с i_core_clk always @(posedge i_core_clk) begin q1 <= q; q2 <= q1; end endmodule
  2. Помогло! Виной всему был звон в проводах. Странно, что его влияние проявляется только при одновременном приёме и передачи. Да я бы смирился с отсутствием o_irq. В конце концов всё равно результат работы SPI приводить в домен основного клока, там его(o_irq) и буду формировать. Всем неравнодушным огромнейшое спасибо!
  3. Сейчас заметил одну вещь. Если на плате с ПЛИС зажать снизу пальцем контакты SPI, то всё начинает приниматься правильно даже на частоте 18МГц. Может подтяжку на все входы сделать?
  4. Удвоитель частоты это интересно)) Правда смущает вот это: На крайние меры уж идти не хотелось бы. Если, кроме как через детекторы фронтов (синхронный) SPI не написать, то и фиг с ним. Совсем уж костыльные решения применять не хочется. По синхронному всё ясно, код подправлю. Я на него просто уже давно забил, работает на частоте 9 МГц и ладно... Хочется понять, реально ли написать асинхронный SPI (не зависящий от i_core_clk), который будет работать стабильно. Или асинхронный SPI это ещё больший костыль, чем удвоитель частоты и не стоит тратить на это время?
  5. Это ещё и систем верилог, что ли? Не могу перевести эту строку в верилог: omiso <= tx_shift_reg[$high(tx_shift_reg)];
  6. Это вообще к любому варианту относится. И к синхронному и к асинхронному (в том числе вашему). Даже к самому начальному, на который все очень сильно ругались. Я это с самого начала отметил. Причём даже удалять не обязательно, достаточно просто не производить никаких действий с входным буфером и не выводить его на внешние пины в топ модуле. Не знаю, стоит ли на этом заострять внимание, потому что решением проблемы в синхронном варианте было применение детекторов фронтов по spi_clk и spi_cs. И для меня совсем не понятно, почему без них приём работал отлично (если только приём!), а с отправкой не работало. Хотя, как уже писали, когда в синхронном дизайне вылезают проблемы связанные с асинхронщиной, возникает метастабильность и всё такое... И там уже логического объяснения происходящего быть не может (бесовщина полная может твориться).
  7. Если убрать из кода всё связанное с отправкой по MISO (оставить только приём по MOSI) приём начинает работать правильно и очень стабильно (и на любой скорости). Является ли это подтверждением того, что spi клок подходящего качества?
  8. 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 ); reg [2:0]counter; //счётчик битов //детектор CLK reg clk_1, clk_2; wire clk_pos, clk_neg; assign clk_pos = clk_1 & ~clk_2; assign clk_neg = ~clk_1 & clk_2; //детектор CS reg cs_1, cs_2; wire cs_neg; assign cs_neg = ~cs_1 & cs_2; always @(posedge i_core_clk) begin clk_1 <= i_clk; clk_2 <= clk_1; cs_1 <= i_cs; cs_2 <= cs_1; if(clk_pos && !cs_2) counter <= counter + 1'd1; if(cs_neg) counter <= 3'd0; end //----------------------- MOSI ----------------------------- reg [7:0]sr_rx; //сдвиговый приёмный регистр reg rx_flag; always @(posedge i_core_clk) begin if(clk_pos && !cs_2) begin sr_rx <= {sr_rx[6:0], i_mosi}; if(counter == 3'd7) rx_flag <= 1'd1; end if(rx_flag) begin rx_flag <= 1'd0; o_irq <= 1'd1; o_rx_buf <= sr_rx; end if(o_irq) o_irq <= 1'd0; end //-------------------------- MISO --------------------------------- reg [7:0]sr_tx; //сдвиговый регистр отправки always @(*) begin if(cs_2) o_miso = 1'dZ; else o_miso = sr_tx[7]; end always @(negedge i_core_clk) begin if(o_irq || cs_neg) begin sr_tx <= i_tx_buf; end if(clk_neg && !cs_2 && counter) begin sr_tx <= sr_tx << 1'd1; end end endmodule Симулирую пока внутри квартуса, написание тестбенчей пока не освоил до конца. Знаю, сейчас ругаться будете, но модуль простой и логику работы можно вполне проверить встроенным функциональным симулятором. Сдаётся мне, это тоже будет работать только при соотношении клоков iclk/isclk = 10/1 (минимум).
  9. К мастеру вопросов точно нет. В синхронном варианте связка МК <-> ПЛИС работает, только частота не максимальная, а 9МГц.
  10. Пробовал и просто его на gnd цеплять, без подключения к мастеру. Если к мастеру цепляю, то после инициализации МК сразу подаю 0 и больше не трогаю. Уменьшение скорости SPI тоже не помогает.
  11. Leka, попробовал. Проблема осталась, в выходном порту мусор ((. Лишь изредка нормализуется приём на пару секунд (особенно если свободные контакты руками полапать), но потом сразу же срывается. Что отправляется по MISO даже не смотрел.
  12. А у меня в топ модуле кроме объявления spi_slave модуля пока больше ничего и нет: module top( input wire i_spi_cs, input wire i_spi_clk, input wire i_spi_mosi, output wire o_spi_miso, output wire [7:0]o_rx_buf ); spi_slave spi( i_spi_cs, i_spi_clk, o_spi_miso, i_spi_mosi, o_rx_buf, o_rx_buf //эхо ); endmodule
  13. Сделал так, не помогло module spi_slave( input wire SS, input wire SCLK, output wire MISO, input wire MOSI, output reg [7:0]spirx, input wire [7:0]spitx ); reg [7:0]txbuf; reg [7:0]spireg; reg txsw; reg [2:0]counter; reg clr = 0; always@(negedge SS or posedge clr) begin if(clr) clr <= 0; else clr <= 1; end always @(negedge SCLK or posedge clr) begin if(clr) begin txsw <= 1'b0; counter <= 3'd0; end else begin txsw <= 1'b1; counter <= counter + 1'd1; end end always @(negedge SCLK) begin if(counter == 3'd7) spirx <= spireg; if(counter == 3'd7 || ~txsw) txbuf <= spitx; end always @(posedge SCLK) begin spireg <= {spireg[6:0], MOSI}; end assign miso_mux = (txsw) ? txbuf[3'd7-counter] : spitx[3'd7-counter]; assign MISO = (~SS) ? miso_mux : 1'bz; endmodule синтезируется такая схема: Это вообще как, нормально? А у меня только одна частота по идее, это SCLK. Или ошибаюсь? Частоту SS не знаю, в конкретной железке он у меня вообще на gnd.
  14. Не могли бы вы помочь мне с ними в конкретном случае. Я так понимаю нужно создать файл .sdc. Что необходимо в него записать (желательно с разъяснениями). По теме нагуглил статью, пока с первого раза не осилил информацию.