Перейти к содержанию
    

Циклический сдвиг на Verilog

Во многих(если не во всех) документация по Verilog написано:

что <<< и >>> - операторы циклического сдвига, однако на практике сдвиг получается обычный логический.

 

Чтобы реализовать циклический сдвиг мне пришлось использовать такой код:

reg [7: 0] shift_r;
always@(clk) begin
    shift_r[7] <= shift_r[0];
    shift_r[6:0] <= shift_r[7:1];
end

 

Кто-нибудь может мне объяснить для чего служат операторы <<< и >>>. И чем они отличаются от << и >>?.

Или может кто-нить приведет пример использования операторов циклического сдвига.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот так тоже должно работать

shift_r <= shift_r << 7 | shift_r >> 1;

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот так тоже должно работать

shift_r <= shift_r << 7 | shift_r >> 1;

 

В продолжение: пытаюсь сделать ШИМ

 

 input signed [7:0] Duty;

assign pwm_dir = ($signed(Duty) > 0) ? 1'b0 : 1'b1;
assign pwm_out = ($signed(Duty) > 0) ? Duty_r[0] : ~Duty_r[0];

reg [6:0] Duty_r
always@(posedge clk or negedge rst)
    if (!rst)
       Duty_r <= 0;
    else
       Duty_r <= {Duty_r[0], Duty_r[6: 1]};

 

Однако возникла заминка. В какой момент времени мне, чтобы ШИМ работал корректно, можно(или нужно) изменять Duty?

 

Есть подсказки? :rolleyes:

 

На ум пришла такая идея:

        input signed [iDutyWidth - 1: 0] Duty;
    output pwm_out, pwm_dir;
    
    assign pwm_dir = ($signed(Duty) > 0) ? 1'b0 : 1'b1;
    assign pwm_out = ($signed(Duty) > 0) ? Duty_r[0] : ~Duty_r[0];
    
    reg [3:0] pwm_state;
    reg [iDutyWidth - 2: 0] Duty_r;
    always@(posedge clk or negedge rst)
        if (!rst) begin
            Duty_r <= 0;
            pwm_state <= 0;
        end
        else begin
            pwm_state <= pwm_state + 1'b1;
            if (pwm_state == 0)
                Duty_r <= Duty[iDutyWidth - 2: 0];
            else
                Duty_r <= {Duty_r[0], Duty_r[iDutyWidth - 2: 1]};
        end

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странный (мягко выражаясь) у вас ШИМ. ШИМы обычно делают на счетчике и компараторе, а у вас непонятный какой то сдвиговый регистр

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

написал

module a_v (
    inclk0,
    inclk1,
    shift_r
    );

    output [7:0] inclk0;
    input inclk1;
    output [7:0] shift_r;
    
    initial
    begin
        inclk0 = 8'b1000_0100;
        shift_r = 8'b1000_0100;
    end
    
    always @(posedge inclk1)
    begin
        inclk0[7:0] <= {inclk0[0], inclk0[7:1]};
        shift_r <= shift_r << 7 | shift_r >> 1;
    end    
endmodule

что не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это синтезируется? Объявлять регистры уже не нужно? Я отстал от жизни.

просто сдвиг норм, а циклический нет

 

а щас че не так?

module a_v (
    inclk0,
    inclk1,
    shift_r
    );

    output logic [7:0] inclk0;
    input logic inclk1;
    output logic [7:0] shift_r;

    logic [7:0] inclk0_r;
    logic [7:0] shift_r_r;

    initial
    begin
        inclk0_r = 8'b1000_0100;
        shift_r_r = 8'b1000_0100;
    end

    always @(inclk1)
    begin
        inclk0_r[7:0] <= {inclk0_r[0], inclk0_r[7:1]};
        shift_r_r <= shift_r_r << 7 | shift_r_r >> 1;
    end

    assign inclk0 = inclk0_r;
    assign shift_r = shift_r_r;
endmodule

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

просто сдвиг норм, а циклический нет

А сдвиг по фронту как у вас (posedge inclk1) ?! Предполагает регистр.

 

Попробуйте скомпилить -- что вам поругается синтезатор.

Изменено пользователем x736C

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ничего, кроме

Warning (10235): Verilog HDL Always Construct warning at a_v.v(22): variable "inclk0_r" is read inside the Always Construct but isn't in the Always Construct's Event Control

если posedge убрать

и тип данных хоть reg, хоть logic

Изменено пользователем stu

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 
module a_v (
   inclk0,
   inclk1,
   shift_r
   );

   output reg [7:0] inclk0;
   input inclk1;
   output reg [7:0] shift_r;

   initial
   begin
       inclk0 = 8'b1000_0100;
       shift_r = 8'b1000_0100;
   end

   always @(posedge inclk1)
   begin
       inclk0[7:0] <= {inclk0[0], inclk0[7:1]};
       shift_r <= shift_r << 7 | shift_r >> 1;
   end    
endmodule

 

в таком варианте циклический сдвиг получается

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот код. не работает. кто пишет "работает", пробовали?

module a_v (
    inclk0,
    inclk1,
    shift_r
    );

    output reg [7:0] inclk0;
    input logic inclk1;
    output reg [7:0] shift_r;

    reg [7:0] inclk0_r;
    reg [7:0] shift_r_r;

    initial
    begin
        inclk0_r = 8'b1000_0100;
        shift_r_r = 8'b1000_0100;
    end

    always @(posedge(inclk1))
    begin
        inclk0_r[7:0] <= {inclk0_r[0], inclk0_r[7:1]};
        shift_r_r <= shift_r_r << 7 | shift_r_r >> 1;
    end

    assign inclk0 = inclk0_r;
    assign shift_r = shift_r_r;
endmodule

Изменено пользователем stu

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...