2016-11-22 3 views
0

Я пытаюсь манипулировать своими часами, используя мой собственный модуль делителя часов.Как изменить и управлять часами в SystemVerilog

module clockDivider(input logic input0, 
        input logic input1, 
        input logic clock, 
        output logic y); 

// 00 = stop, 01 = slow, 10 = medium, 11 = fast; 

if(~input1 & ~input0)  /*stop clock*/ ; 
else if(~input1 & input0) /*slow*/ ; 
else if(input1 & ~input0) /*medium*/ ; 
else if(input1 & input0) /*fast*/ ; 

endmodule 

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

А также есть ли какие-либо веб-сайты, кроме doulos? Я думаю, что это не совсем понятно и содержит лишь небольшое количество информации о System Verilog.

Благодаря

+1

Systemverilog LRM (IEEE Std 1800-2012) свободно доступен на веб-сайте IEEE. – toolic

+0

Спасибо, @toolic. Только для того, чтобы помогать другим, каждый может получить доступ к SystemVerilog LRM из [здесь] (http://standards.ieee.org/getieee/1800/download/1800-2012.pdf) –

ответ

1

По slow, medium и fast, я буду считать, что самые быстрыми вы ожидаете от этой логики является скоростью самой clock то есть вы реализующим делителя тактовой частоты.

я предположил, что следующие действия:

slow = 0,25 * часы

medium = 0,5 * перевести часы

fast = часы

module clockDivider(input logic reset, 
        input logic input0, 
        input logic input1, 
        input logic clock, 
        output logic y); 

// 00 = stop, 01 = slow, 10 = medium, 11 = fast; 
    logic delayed_y; 
    logic delayed_delayed_y; 
    logic [1:0] counter; 

    always @(posedge clock) begin 
    if (reset) begin 
     counter <= 'h0; 
    end 
    else begin 
     counter <= counter+1'b1; 
    end 
    end 

    always @(posedge clock) begin 
    if (reset) begin 
     delayed_y <= 1'b0; 
    end 
    else begin 
     delayed_y <= counter[0]; 
    end 
    end 

    always @(posedge clock) begin 
    if (reset) begin 
     delayed_delayed_y <= 1'b0; 
    end 
    else begin 
     delayed_delayed_y <= counter[1]; 
    end 
    end 

    always @(*) begin 
    if (reset) begin 
     y = 1'b0; 
    end 
    else begin 
     /*stop clock*/ 
     if(~input1 & ~input0) begin 
     y = 1'b0; 
     end 

     /*slow*/ 
     else if(~input1 & input0) begin 
     y = delayed_delayed_y; 
     end 

     /* medium*/ 
     else if(input1 & ~input0) begin 
     y = delayed_y; 
     end 

     /* fast */ 
     else if(input1 & input0) begin 
     y = clock; 
     end 
    end 
    end 

endmodule 

Вы можете найти рабочий пример здесь: https://www.edaplayground.com/x/5J75

Примечание: Если вы хотите умножить часы, вам необходимо использовать DCM на своей целевой FPGA. Существует еще один метод с 2-входным XOR-затвором и буфером синхронизации, но я бы придерживался DCM.

+0

Прежде всего, спасибо вам за интерес. Я задаю этот вопрос, чтобы быть уверенным на самом деле. Задержка delay_y = medium и delayed_delayed_y = slow? –

+0

@AhmetBatuOrhan Да. 'delayed_y' составляет 1/2 частоты часов и' delayed_delayed_y' составляет 1/2 частоты 'delayed_y' => 1/4 частоты' clock' – noobuntu

+1

Логика для назначения 'delayed_y' и' delay_delayed_y' вы написали являются выведенными защелками с асинхронной обратной связью. Моделирование и синтез не совпадают. Они должны быть на флопе с 'posedge'. Предпочтительно оба должны быть наложены с помощью '@ (posedge clock)', чтобы уменьшить смещение фазы выходного края таймера – Greg

2

Вы можете непосредственно имеющие по модулю N счетчика разделить частоты на N.

Пусть здесь ваши все 3 вида часов.

00 - No Clock 
01 - Clock/4 
02 - Clock/2 
03 - Clock 

Вот код для этого. Обратите внимание, что его концептуальный код не проверен.

module clockDivider(input logic input0, 
        input logic input1, 
        input logic clock, 
        input logic reset, 
        output logic y); 

// 00 = stop, 01 = slow, 10 = medium, 11 = fast; 
parameter mod = 2; 
reg [mod-1:0] count, max; 

assign y = (~input1 & ~input0) ? 1'b0 : count[mod-1]; /*stop clock*/ 

always @ (posedge clock) 
begin 
if(~input1 & input0) /*slow*/ 
    max <= (1 << (mod-2)) - 1'b1; 
else if(input1 & ~input0) /*medium*/ 
    max <= (1 << (mod-1)) - 1'b1; 
else if(input1 & input0) /*fast*/ 
    max <= (1 << mod) - 1'b1; 
end 

always @ (posedge clock, negedge reset) 
begin 
    if (!reset) 
    count <= 0; 
    else if (count == max) 
    count <= 0; 
    else 
    count <= count + 1'b1; 
end 
endmodule 
+0

Пожалуйста, отметьте как ответ, если сочтет это подходящим. :) –