2016-11-22 3 views
-1

Я пытаюсь реализовать передатчик I2S в verilog. Техническое описание для него: https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdfI2S Transmitter Verilog Реализация не работает

Я написал код, но моя линия SD задерживается на 1 такт, когда я его тестирую. Может ли кто-нибудь проверить мою реализацию?

module Transmiter(
    input signed [23:0] DLeft, input signed [23:0] DRight, input WS, input CLK, 
    output reg SD 
    ); 

    wire PL; 
    reg Q1,Q2; 
    reg [23:0] shift_reg; 
    reg [23:0] Tdata; 


    assign PL = Q1^Q2; 



    always @(posedge CLK) 
    begin 
     Q1 <= WS; 
     Q2 <= Q1; 
    end 


    always @(Q1) begin 
     if (Q1) 
     begin 
     Tdata <= DRight; 
     end 
     else 
      begin 
      Tdata <= DLeft; 
      end 
    end 



    always @(negedge CLK) 
     begin 

      if(PL) 
      begin 
       shift_reg <= Tdata; 
      end 
      else begin 

      SD <= shift_reg[23]; 
      shift_reg <= {shift_reg[22:0],1'b0}; 
      end 
     end 


endmodule 

EDIT: вот изображение сигнала image

TEST CODE BENCH:

module Transmitter_tb(

    ); 


    reg CLK, WS; 
    reg [23:0] dataL; 
    reg [23:0] dataR; 

    wire SDout; 



    Transmiter UT(dataL, dataR, WS, CLK, SDout); 

    initial begin 
    dataL = 24'hF0F0FF; #2; 
    dataR = 24'h0000F0; #2; 

    end 



    always begin 
    CLK=0; #20; 
    CLK=1; #20; 
    end; 

     always begin 
    WS=0; #1000; 
    WS=1; #1000; 
    end; 





endmodule 
+0

Пожалуйста, добавьте более подробную информацию - ваш код testbench, вашу форму сигнала, где вы видите SD с задержкой, и где именно проблема? – noobuntu

+0

'always @ (Q1)' должен быть 'always @ (Q1 или DRight или DLeft)' не уверен, что это проблема. – Hida

+0

@Hida DRight и DLeft являются постоянными значениями, я ищу изменения в Q1. На основе Q1 либо R, либо L загружается в Tdata – user1775297

ответ

1

Ваш negedge блок содержит if-else конструкцию и только когда-либо вычислить один или другой на одном часы край. SD поэтому не изменит значение, когда PL высокий.

Кроме того, в вашем коде используются неблокирующие назначения (<=). Это примерно означает, что изменения не будут оцениваться до конца всегда блока. Поэтому, даже если SD <= shift_reg[23] после shift_reg <= Tdata он не примет новое значение в shift_reg[23], но использует предыдущее значение. Если вы хотите, чтобы SD менялся сразу после изменения shift_reg[23], вам нужно сделать это комбинаторно.

Это должно работать:

always @(negedge CLK) 
    begin 

     if(PL) 
     begin 
      shift_reg <= Tdata; 
     end 
     else 
      shift_reg <= {shift_reg[22:0],1'b0}; 
    end 
    assign SD = shift_reg[23]; 

Рабочий пример: https://www.edaplayground.com/x/4bPv

На стороне записки я до сих пор не уверен, что DRight и DLeft фактически являются постоянными, я могу видеть, что они находятся в вашем ТБ но не имеет смысла, что данные для вашего I2S постоянны. Ваша текущая конструкция, вероятно, создаст защелку (вместо MUX), и мы, как правило, не хотим тех, что в нашем дизайне.

+0

Когда я говорю, что DRight и DLeft являются постоянными, я имею в виду, что моя инструкция if-else в коде не зависит от них. Потому что я просто копирую один из них в место tempdata, основанное на значении Q1. В общем, да, DRight и DLeft будут меняться, но я не копирую их в временное место, когда они меняются, только когда Q1 меняется. Q1 выбирает либо DRight, либо DLeft. быть перенесенным. – user1775297

+0

Это исправление работает, и я понимаю, что вы имеете в виду сейчас. Я также должен был изменить тактовый цикл WS до 960ns. Но сейчас все работает. Спасибо. – user1775297

0

Вы должны очистить ваше использование блокировки против неблокирующих утверждений:

Всегда использовать неблокируемые assigments, что означает «< =», в Хронометрировали отчетности.

Всегда используйте блокирующие привязки, что означает «=», в комбинационных (не clocked) операциях.

Это общеотраслевая рекомендация, а не личное мнение. Вы можете найти эту рекомендацию много мест, смотри, например:

http://web.mit.edu/6.111/www/f2007/handouts/L06.pdf

Список sensitivtity быть неполным (как указывает @Hida) также может вызвать проблемы.

Попытайтесь исправить эти две вещи и посмотреть, начнет ли она работать больше, как ожидалось.

Также обратите внимание, что вы используете Q1 (среди других сигналов) для генерации вашего сигнала PL. Если вход WS не является синхронным с вашими локальными часами (как я полагаю, это не так), перед тем, как начать использовать выход, вам нужно поставить еще один флоп (т. Е. Два в ряд), чтобы избежать проблем с метастабильностью. Но вы не увидите этого в RTL-симуляции.