How to sign-renew a number in Verilog

I am working on a simple sign extender in Verilog for a processor that I create for computer architecture.

Here's what I have so far: [EDIT: slightly changed the select statement]

`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 that while (CLK == 1) thinks this will solve my problem, and I believe this is an infinite loop. When I try to verify this in iSim, the circuit is never initialized.

I also tried removing the copy syntax and just doing extended [8] = extend [7] etc. for [8] - [15], but the same result arises, so I'm 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?

+6
verilog vlsi
source share
3 answers

You almost got it ...

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

You also miss the edge of the watch for the "40" test. Try this, and let me know how you are doing ...

+13
source share

We can use the $signed syntax to sign the extension

 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 
+10
source share

By the way, your assignable module is purely combinational, so it should not contain clk, this is another way to make 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 ;) 
+2
source share

All Articles