2010-11-14 11 views
6

Estoy trabajando en un extensor de señal simple en Verilog para un procesador que estoy creando para Arquitectura de Computadora.Cómo firmar y extender un número en Verilog

Esto es lo que tengo hasta ahora: [EDIT: Se ha cambiado la declaración de selección poco]

`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 

he añadido el (== 1 CLK), mientras que el pensamiento que solucionaría mi problema, que creo que es un bucle infinito Cuando trato de probar esto en iSim, el circuito nunca se inicializa.

También intenté eliminar la sintaxis de copiado y simplemente extendí [8] = extender [7] etc. para [8] - [15], pero ocurre el mismo resultado, así que estoy bastante seguro de que la sintaxis más interna es correcto.

Aquí está el archivo de prueba:

`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 

Alguna idea de cómo puedo hacer esto con éxito?

+0

Mire sus '' begin's y end's ... – Marty

Respuesta

13

Es casi lo consiguió ...

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

También se está perdiendo un flanco de reloj para la prueba del '40'. Prueba de esto, & que me haga saber cómo le va ...

+0

Gracias, eso es precisamente lo que me faltaba! –

10

Podemos utilizar la sintaxis $signed a firmar extender

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 
+1

Tenga en cuenta que algunas herramientas generarán una advertencia acerca de la falta de coincidencia de ancho, porque '$ signed (unextended)' sigue siendo solo 8 bits antes de que se asigne a 'extended' – minexew

2

Por cierto que su módulo de asignación es pura combinatoria lo que no debería contener un CLK , esta es otra forma de hacer su módulo:

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 

;)