Jump to content
    

Циклический сдвиг на 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

 

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

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

 

 

Share this post


Link to post
Share on other sites

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

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

 

 

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

 

Share this post


Link to post
Share on other sites

написал

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

что не так?

Share this post


Link to post
Share on other sites

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

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

 

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

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

Share this post


Link to post
Share on other sites

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

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

 

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

Edited by x736C

Share this post


Link to post
Share on other sites

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

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

Edited by stu

Share this post


Link to post
Share on other sites

 
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

 

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

Share this post


Link to post
Share on other sites

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

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

Edited by stu

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...