Comment signer-étendre un nombre Verilog
Question
Je travaille sur un simple signe d'allongement dans Verilog pour un processeur Je crée pour l'architecture informatique.
Voici ce que j'ai à ce jour: [EDIT: Modification de la déclaration de sélection légèrement]
`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
J'ai ajouté le temps (CLK == 1) la pensée qui résoudrait mon problème, que je crois est une boucle infinie. Lorsque je tente de le tester dans iSim, le circuit n'initialise.
J'ai aussi essayé de supprimer la syntaxe et la copie fait qu'exercer étendu [8] = extension [7], etc. pour [8] - [15], mais le même résultat se produit, donc je suis assez sûr que la syntaxe est plus à l'intérieur correct.
Voici le fichier de test:
`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
Toutes les idées comment je peux le faire avec succès?
La solution
Tu as failli got it ...
always @( posedge clk ) begin
extended[15:0] <= { {8{extend[7]}}, extend[7:0] };
end
Vous manque également une horloge de bord pour le test « 40 ». Essayez ceci, et laissez-moi savoir comment vous allez ...
Autres conseils
Nous pouvons utiliser la syntaxe $signed
pour vous étendre
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
Par la façon dont votre assign module est pur combinatoires donc il ne doit pas contenir clk, ceci est une autre façon de faire votre 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
;)