Арифметическое смещение вправо не работает в Verilog HDL - PullRequest
0 голосов
/ 25 февраля 2019

Я строю блок сдвига, способный к арифметическому и логическому сдвигу вправо и логическому сдвигу влево в зависимости от передаваемых ему управляющих сигналов.Однако арифметический выходной сигнал оператора правого смещения генерирует выходные данные, аналогичные этому логическому оператору правого сдвига, т. Е. Расширение знака не происходит.

Основной код

`timescale 1ns / 1ps

module shift_unit(
    input [15:0] a,
    input [3:0] b,
     input clk,
    input isLSL,
    input isLSR,
    input isASR,
    output reg [15:0] result
    );
wire [15:0] LSL_result, LSR_result, ASR_result;

LSL lsl(a, b, clk, isLSL, LSL_result);
LSR lsr(a, b, clk, isLSR, LSR_result);
ASR asr(a, b, clk, isASR, ASR_result);

always@(posedge clk) begin
case({isLSL, isLSR, isASR})
    3'b001: result <= ASR_result;
    3'b010: result <= LSR_result;
    3'b100: result <= LSL_result;
endcase
end

endmodule

LSL-код:

`timescale 1ns / 1ps
module LSL(
    input [15:0] a,
    input [3:0] b,
     input clk,
     input isLSL,
    output [15:0] out
    );

reg [15:0] result;
always@(posedge clk) begin
    if(isLSL)   result = a << b;
end
assign out = result;

endmodule

Код LSR:

`timescale 1ns / 1ps
module LSR(
    input [15:0] a,
    input [3:0] b,
    input clk,
    input isLSR,
    output [15:0] out
    );

reg [15:0] result;
always@(posedge clk) begin
    if(isLSR)   result = a >> b;
end
assign out = result;

endmodule

Код ASR:

`timescale 1ns / 1ps
module ASR(
    input [15:0] a,
    input [3:0] b,
    input clk,
    input isASR,
    output [15:0] out
    );

reg [15:0] result;
always@(posedge clk) begin
    if(isASR)   result = a >>> b;
end
assign out = result;

endmodule

И, наконец, тестовая среда:

`timescale 1ns / 1ps

module shift_unit_test;
    reg [15:0] a;
    reg [3:0] b;
    reg clk;
    reg isLSL;
    reg isLSR;
    reg isASR;

    wire [15:0] result;

    shift_unit uut (
        .a(a), 
        .b(b), 
        .clk(clk), 
        .isLSL(isLSL), 
        .isLSR(isLSR), 
        .isASR(isASR), 
        .result(result)
    );

    always #5 clk = ~clk;

    initial begin
        clk = 1'b0;
        a = 16'b1100101011001010;
        b = 4;
        {isLSL, isLSR, isASR} = 3'b100; #100;
        {isLSL, isLSR, isASR} = 3'b010; #100;
        {isLSL, isLSR, isASR} = 3'b001; #100;
    end

endmodule

Приведенный выше код был смоделирован с использованиемXilinx ISE 14.7.Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 25 февраля 2019

Вам нужно работать с signed сигналами, чтобы получить расширение знака.

module ASR(
    input wire signed [15:0] a,
    input [3:0] b,
    input clk,
    input isASR,
    output reg signed [15:0] out
    );


always@(posedge clk) begin
    if(isASR)   out = a >>> b;
end

endmodule
...