算术右移在Verilog HDL中不起作用

时间:2019-02-25 18:17:29

标签: verilog logical-operators bit-shift

我正在构建一个移位单元,它可以算术和逻辑上向右移位,并根据提供给它的控制信号进行逻辑上向左移位。但是,算术右移运算符输出会生成类似于该逻辑右移运算符的输出,即不会出现符号扩展。

主要代码

`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 :(得分:0)

您需要使用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