How to sign-extend a number in Verilog
Solution 1
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...
Solution 2
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
);
[email protected](posedge clk)
begin
extended <= $signed(unextended);
end
endmodule
Solution 3
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
;)
Related videos on Youtube
Comments
-
Alex Mullans almost 2 yearsI'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 endmoduleI 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 endmoduleAny ideas how I can do this successfully?
-
minexew almost 5 yearsNote that some tools will raise a warning about width mismatch, because$signed(unextended)is still just 8 bits before it's assiged toextended