creando un bcd squarer usando verilog

0

Básicamente, estoy usando una tabla de búsqueda para generar en bcd el cuadrado de un solo dígito bcd.

El problema que tengo es que no está dando la respuesta correcta.

Por ejemplo: el resultado que obtengo por el cuadrado de estos números es:

1 = 1

2 = 4

4 = 10

5 = 19

10 = 64

como pueden ver, tengo que separar MBCD y LBCD y luego concatenarlos.

Aquí está mi código:

module bcdsquarer(input[3:0]bcdin, output[7:4]Mbcd, output[3:0]Lbcd);
parameter msb = 16;
parameter lsb = 8;
reg [lsb-1:0]ROM[0:msb-1];
integer i;
initial 
    begin
    for(i=0; i<16; i = i+1)
        begin
            ROM[i] = i**2;
        end
    end
    assign {Mbcd,Lbcd} = ROM[bcdin];
endmodule

¿Alguien ve dónde cometí un error?

editar: Bien, entonces sé que tengo que convertir de binario a bcd. Tengo un código que convierte, pero ¿cómo lo implemento con mi bcdsquarer?

aquí está mi código

module B2BCD(B,hundreds,tens,ones);
    input [7:0] B;
    output [3:0] hundreds;
    output [3:0] tens;
    output [3:0] ones;
    integer x;
    reg [3:0] hundreds, tens, ones;
    always @(B)
    begin
        x=B;
       hundreds=0; tens=0; ones = 0;
       if(x>99)begin hundreds =hundreds +1; x =x-100; end
       if(x>99)begin hundreds =hundreds +1; x =x-100; end
       repeat(9)
       begin
       if(x>9)begin tens = tens +1; x =x-10; end
       end

       ones =x;
    end
endmodule

Intenté implementarlo de esta manera: (solo obtengo x para mis resultados ahora)

module bcdsquarer(bcdin,Mbcd,Lbcd,tens,ones);
parameter msb = 16;
parameter lsb = 8;

input[3:0]bcdin;

output[7:4]Mbcd;
output[3:0]Lbcd;

output [3:0] tens;
output [3:0] ones;

integer x;
reg[3:0] tens;
reg[3:0] ones;
    always @(bcdin)
    begin
        x=bcdin;
       tens=0; ones = 0;
       begin
       if(x>9)begin tens = tens +1; x =x-10; end
       end

       ones =x;
    end

assign Mbcd = tens;
assign Lbcd = ones;

reg [lsb-1:0]ROM[0:msb-1];
integer i;
initial 
    begin
    for(i=0; i<16; i = i+1)
        begin
            ROM[i] = i**2;
        end
    end
    assign {Mbcd,Lbcd} = ROM[bcdin];
endmodule
    
pregunta CharleBarkely123

2 respuestas

2

Básicamente, las operaciones de Verilog se realizan en binary y no en BCD . Entonces, si haces algo como i**2 , el resultado estará en binario. Dividir los nibbles no convierte el binario a BCD.

Tienes dos opciones. O bien:

  1. Continúe e implemente una conversión de binario a BCD; puede hacer esto como una función, que debido a que se usa en un bloque inicial no debe inferir ningún hardware, suponiendo que sea algo que el sintetizador pueda calcular. O

  2. Calcule todos los valores de antemano y simplemente inicialice la LUT que ha diseñado con los valores precomputados. Esta es, con mucho, la forma más fácil, y para ser honesto, probablemente (o así lo he encontrado) la forma habitual de hacerlo.

En la última opción, puedes hacerlo de varias maneras. Una es usar algo como Excel para calcular una tabla de valores e inicializar la LUT a partir de eso, por ejemplo. leyendo los valores a su vez de un archivo (Verilog tiene macros para esto como $ readmem).

Alternativamente, si se siente aventurero, puede crear un script (por ejemplo, TCL) que crea los valores y genera un archivo Verilog que contiene el código para toda la LUT, incluida la iniciación, o crea un archivo de inicialización de memoria que puede cargar en su LUT. Esta opción no es realmente útil para este ejemplo en particular, pero es genial para los más complejos, tal vez guárdela por una vez que haya adquirido más experiencia.

    
respondido por el Tom Carpenter
0

Este es un código que es similar al que usé para los dígitos cuadrados al cuadrado (0-9).

module squarer(
input [3:0] B,
output [7:0] SQ
);

localparam NL=16;
localparam Nb=8;
reg [Nb-1:0]ROM [0:NL-1];
integer i;
initial
begin

ROM[0]=8'b0000_0000;
ROM[1]=8'b0000_0001;
ROM[2]=8'b0000_0100;
ROM[3]=8'b0000_1001;
ROM[4]=8'b0001_0110;
ROM[5]=8'b0010_0101;
ROM[6]=8'b0011_0110;
ROM[7]=8'b0100_1001;
ROM[8]=8'b0110_0100;
ROM[9]=8'b1000_0001;

end
assign SQ=ROM[B];
endmodule

El código de simulación fue:

module testsq;
reg [3:0] B;
wire [7:0] SQ;

squarer uut (
    .B(B), 
    .SQ(SQ)
);

initial begin
B = 0;

#10  B = 0;
#10  B = 1;
#10  B = 2;
#10  B = 3;
#10  B = 4;
#10  B = 5;
#10  B = 6;
#10  B = 7;
#10  B = 8;
#10  B = 9;

#10 $finish;
end

endmodule

Esto dio los valores correctos para 0-9, 0 = 00, 1 = 01, 2 = 04, 3 = 09, 4 = 16, 5 = 25 ... 9 = 81. Espero que esto ayude, no estoy seguro si responde exactamente a la pregunta.

    
respondido por el loldotasotis

Lea otras preguntas en las etiquetas