2016-08-17 2 views
1

Я пишу код для взаимодействия с this ЦАП для создания синусоидальной волны. У меня есть синус LUT, который генерирует значения просто отлично, а также контроллер ЦАП. Контроллер выводит CS на низкий уровень, подает 16-битное целое число за раз, и импульсы CS до максимума после 16 отсчетов. Так как он выполняет импульсы, он также посылает импульс включения в sin LUT для подсчета еще одного номера. Этот код, похоже, работает не очень хорошо, так как я получаю всплески вывода. Это связано с тем, что часы считывают CS как низкий, когда он должен быть высоким (рисунок 1), заставляя ЦАП считывать 17 бит (другими словами, читать MSB текущего номера как младший бит LSB), что вызывает неудобство шипы (рисунок 2).Как я могу улучшить свой код, чтобы не получить ошибки времени?

Как я могу лучше организовать этот код, чтобы свести к минимуму риск столкнуться с этой проблемой синхронизации?

module DAC_Control(
    input [15:0]data_in, 
    input counter_enable, 
    input clk, 
    input rst, 
    output data_out, 
    output reg cs, 
    output reg enable 
); 

//bit counter 
    reg [3:0] bit_counter; 

//to help with shifting 
    reg [15:0] shifter; 

//shifter 
    always @(posedge (clk)) begin 
    if (rst) begin 
     bit_counter <= 4'b0; 
     shifter <= 0; 
     end 
    else if (counter_enable == 1) begin 
     shifter <= data_in; 
     bit_counter <= 4'b0; 
    end 
    else begin 
     shifter <= shifter << 1; // shifting 
     bit_counter <= bit_counter + 1'b1; // counter 
    end 
    end 

    reg cs_hold; 

    always @(posedge (clk)) begin 
    if (rst) begin 
     enable <= 1'b0; 
     cs <= 1'b1; 
     end 
    else if (bit_counter == 4'b1110) begin 
     enable <= 1'b1; 
     cs <= 1'b0; 
    end 
    else if (bit_counter == 4'b1111) begin 
     enable <= 1'b0; 
     cs <= 1'b1; 
    end 
    else if (cs_hold == 1) begin 
     enable <= 1'b0; 
     cs <= 1'b1; 
    end 
    else begin 
     enable <= 1'b0; // generate enable signals 
     cs <= 1'b0; 
    end 
    end 


    assign data_out = shifter[15]; 

endmodule 

Рисунок 1. Желтый DIN, Синий CS, зеленый часы

figure 1

Рисунок 2. Выходной сигнал ЦАП

figure 2

ответ

2

Я не знаю, из какого поставщика ваша FPGA, однако у большинства из них есть ограничения по времени, которые позволяют вам определить взаимосвязь между вашими часами и данными. Они используют идею виртуальных часов. Подумайте об этом, как есть внешние часы, и вы можете сказать, что разница между часами. Если часы напрямую генерируются из FPGA, а не из какого-то внешнего источника, я думаю, вы можете установить некоторые из значений CLK на 0.

Установив эти ограничения, вы делаете так, чтобы выход данных перемещался относительно к clk, и он будет «последовательным и контролируемым».

+----------+    +--------+ 
| FPGA  |----Data_out--->| DAC | 
+----------+    +--------+ 
    CLKs /\    CLKd /\ 
      |      | 
      +-------sys_clk--------+ 

Это решение для устройств Altera, использующих SDC для вывода данных.

#specify the maximum external clock delay to the FPGA 
set CLKs_max 0.200 
#specify the minimum external clock delay to the FPGA 
set CLKs_min 0.100 
#specify the maximum external clock delay to the external device 
set CLKd_max 0.200 
#specify the minimum external clock delay to the external device 
set CLKd_min 0.100 
#specify the maximum setup time of the external device 
set tSU 0.125 
#specify the minimum setup time of the external device 
set tH 0.100 
#specify the maximum board delay 
set BD_max 0.180 
#specify the minimum board delay 
set BD_min 0.120 
#create a clock 10ns 
create_clock -period 10 -name sys_clk [get_ports sys_clk] 
#create the associated virtual input clock 
create_clock -period 10 -name virt_sys_clk 
#create the output maximum delay for the data output from the FPGA that 
#accounts for all delays specified 
set_output_delay -clock virt_sys_clk \ 
    -max [expr $CLKs_max + $BD_max + $tSU - $CLKd_min] \ 
    [get_ports {data_out[*]}] 
#create the output minimum delay for the data output from the FPGA that 
#accounts for all delays specified 
set_output_delay -clock virt_sys_clk \ 
    -min [expr $CLKs_min + $BD_min - $tH - $CLKd_max] \ 
    [get_ports {data_out[*]}] 

С другой стороны, если вы не можете контролировать отношения между данными и часами с ограничениями, которые, кажется, сырный даже предположить (И если это правда, то пожалуйста скажите мне поставщику, так что я могу остаться с ними), вы могли бы сделать лучше, следуя предложению предыдущего ответа, изменив свой постулат на отрицание. Просто имейте в виду, что это может быть гибким от сборки для сборки, поскольку выход не может быть ограничен так, как вы хотите.

+0

Спасибо, это то, что я пытался понять на некоторое время. У меня есть четыре оставшихся вопроса, основанных на этом: 1- Я получаю эти максимальные и минимальные значения из ограничений времени DAC, правильно? 2. Можете ли вы рассказать о том, что вы имеете в виду, когда говорите «вывод данных перемещен относительно данных». 3. Моя доска от Xilinx. Я просмотрел руководство по ограничениям времени и не видел, чтобы код выполнялся эти ограничения, любая идея, где я могу их найти/что делать в Google? 4- у вас есть предложения по дальнейшему чтению о часах, которые ориентированы на новичка? – qasddd

+1

1.Да, вы получаете их прямо из спецификации. Вы можете сделать их более жесткими, если хотите, но не слишком тугими, поскольку вы добавляете дополнительную маршрутизацию задержки и потребляете ресурсы в чипе, чтобы заставить его работать. –

+1

2. Я неправильно напечатал это. Я хотел сказать данные относительно часов. Я только что исправил это в ответе. 3. Если вы используете Vivando, вот ссылка ... см. Главу 4. Это не то же самое, что Altera, но я думаю, вы ее получите. Вы говорите, я хочу, чтобы мои данные меняли это много нс после или перед часами. [vivando using constraints] (http://www.xilinx.com/support/documentation/sw_manuals/xilinx2015_1/ug903-vivado-using-constraints.pdf) 4 - Временные ограничения Google Xilinx, и вы должны получить несколько презентаций и уроков в университете там. –

Смежные вопросы