如何在 Verilog 中对数字进行符号扩展

发布于 2024-10-01 20:16:43 字数 1350 浏览 0 评论 0原文

我正在 Verilog 中为我为计算机体系结构创建的处理器开发一个简单的符号扩展器。

这是我到目前为止所得到的:[编辑:稍微更改了选择语句]

`timescale 1ns / 1ps

module SignExtender( CLK, extend, extended );
input[7:0] extend;
input CLK;
output[15:0] extended;

reg[15:0] extended;
wire[7:0] extend;

always
begin
    while (CLK == 1)
    extended[7:0] = extend[7:0];
    extended[15:8] = {8{extend[7]}};
end
endmodule

我添加了 while (CLK == 1) 认为这可以解决我的问题,我认为这是一个无限循环。当我尝试在 iSim 中测试这一点时,电路从未初始化。

我还尝试删除复制语法并仅对 [8]-[15] 执行扩展[8] =扩展[7]等,但出现相同的结果,所以我很确定最里面的语法是正确的。

这是测试文件:

`timescale 1ns / 1ps
module SignExtender_testbench0;

    // Inputs
    reg [7:0] extend;
    reg CLK;

    // Outputs
    wire [15:0] extended;

    // Instantiate the Unit Under Test (UUT)
    SignExtender uut (
        .extend(extend), 
        .extended(extended)
    );

    initial begin
        // Initialize Inputs
        extend = 0;

        #100; // Wait 100 ns for global reset to finish

        extend = -30;
        CLK = 1;
        #10;
        CLK = 0;
        if (extended == -30)
            $display("okay 1");
        else
            $display("fail 1");

        extend = 40;
        #10;
        if (extended == 40)
            $display("okay 2");
        else
            $display("fail 2");

    end

endmodule

有什么想法可以成功地做到这一点吗?

I'm working on a simple sign-extender in Verilog for a processor I'm creating for Computer Architecture.

Here's what I've got so far: [EDIT: Changed the selection statement slightly]

`timescale 1ns / 1ps

module SignExtender( CLK, extend, extended );
input[7:0] extend;
input CLK;
output[15:0] extended;

reg[15:0] extended;
wire[7:0] extend;

always
begin
    while (CLK == 1)
    extended[7:0] = extend[7:0];
    extended[15:8] = {8{extend[7]}};
end
endmodule

I added the while (CLK == 1) thinking that would solve my problem, which I believe is an infinite loop. When I try to test this in iSim, the circuit never initializes.

I also tried removing the copying syntax and just doing extended[8] = extend[7] etc. for [8]-[15], but the same result occurs, so I'm pretty sure that the innermost syntax is correct.

Here's the test file:

`timescale 1ns / 1ps
module SignExtender_testbench0;

    // Inputs
    reg [7:0] extend;
    reg CLK;

    // Outputs
    wire [15:0] extended;

    // Instantiate the Unit Under Test (UUT)
    SignExtender uut (
        .extend(extend), 
        .extended(extended)
    );

    initial begin
        // Initialize Inputs
        extend = 0;

        #100; // Wait 100 ns for global reset to finish

        extend = -30;
        CLK = 1;
        #10;
        CLK = 0;
        if (extended == -30)
            $display("okay 1");
        else
            $display("fail 1");

        extend = 40;
        #10;
        if (extended == 40)
            $display("okay 2");
        else
            $display("fail 2");

    end

endmodule

Any ideas how I can do this successfully?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半城柳色半声笛 2024-10-08 20:16:43

您几乎得到了它...

always @( posedge clk ) begin
    extended[15:0] <= { {8{extend[7]}}, extend[7:0] };
end

您还缺少“40”测试的时钟沿。试试这个,&让我知道你过得怎么样...

You nearly got it...

always @( posedge clk ) begin
    extended[15:0] <= { {8{extend[7]}}, extend[7:0] };
end

You're also missing a clock edge for the '40' test. Try this, & let me know how you get on...

旧瑾黎汐 2024-10-08 20:16:43

我们可以使用语法 $signed 来对扩展进行签名

module signextender(
  input [7:0] unextended,//the msb bit is the sign bit
  input clk,
  output reg [15:0] extended 
);

always@(posedge clk)
  begin 
    extended <= $signed(unextended);
  end
endmodule

We can use the syntax $signed to sign extend

module signextender(
  input [7:0] unextended,//the msb bit is the sign bit
  input clk,
  output reg [15:0] extended 
);

always@(posedge clk)
  begin 
    extended <= $signed(unextended);
  end
endmodule
尘世孤行 2024-10-08 20:16:43

顺便说一句,您的模块分配是纯组合的,因此它不应包含 clk,这是执行模块的另一种方法:

module sign_ext
             (
              unextend,
              extended
             );

input  [15:0] unextend;
output [31:0] extended;

assign extended = {{16{unextend[15]}}, unextend};

endmodule

//TB

module tb_sign_ext;

reg  [15:0] unex;
wire   [31:0] ext;

sign_ext TBSIGNEXT
                  (
                   .unextend(unex),
                   .extended(ext)
                  );

initial
begin
   unex = 16'd0;
end


initial 
begin
   #10 unex = 16'b0000_0000_1111_1111;
   #20 unex = 16'b1000_0000_1111_1111;
end

endmodule

;)

By the way your module assign is pure combinational so it should not contain a clk, this is another way of doing your module:

module sign_ext
             (
              unextend,
              extended
             );

input  [15:0] unextend;
output [31:0] extended;

assign extended = {{16{unextend[15]}}, unextend};

endmodule

//TB

module tb_sign_ext;

reg  [15:0] unex;
wire   [31:0] ext;

sign_ext TBSIGNEXT
                  (
                   .unextend(unex),
                   .extended(ext)
                  );

initial
begin
   unex = 16'd0;
end


initial 
begin
   #10 unex = 16'b0000_0000_1111_1111;
   #20 unex = 16'b1000_0000_1111_1111;
end

endmodule

;)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文