Convertir bmp de 8 bits a bmp de semitono

2

Ahora estoy explicando mi pregunta en detalle mientras me doy cuenta de que no expliqué bien mi pregunta.

Soy un principiante en Verilog. Para aprender el idioma estoy escribiendo algunas aplicaciones de muestra.
Actualmente estoy escribiendo el código Verilog para convertir una imagen BMP de 8 bits en una imagen BMP de medio tono usando Floyd-Steinberg algoritmo. Básicamente estoy convirtiendo píxeles de 8 bits en 1 bit utilizando dicho algoritmo.

Encontré el código de ejemplo para este algoritmo en el libro Diseño digital avanzado con el Verilog HDL - Michael D. Ciletti en la página número 555. He simulado con éxito el diseño en ModelSim.

El problema es que el ejemplo se da para una imagen de tamaño 6 x 8, pero para aprender y practicar, estoy tratando de convertir este código para diferentes formatos y tamaños. Como primer objetivo, trato de modificar este código (que ya he entendido bien) para que funcione con imágenes de tamaño 1000 x 1000. Como el ejemplo fue solo para 48 píxeles (6 x 8), fue más fácil escribir las instrucciones. Dentro del módulo manualmente, como se muestra en el código que se proporciona a continuación. Pero si tengo 10,00000 píxeles (1000 x 1000), ¿cómo puedo cambiar el código? No puedo escribir tales ecuaciones:

  PPDU a0(err_1,htpv_1[1],8'b00,8'b00,8'b00,8'b00,pixel_1);

10,00000 manualmente (por favor vea el código que figura a continuación).

Supongo que tiene que haber alguna forma de automatizar este trabajo.

En C puedo usar para bucles para autoamting muchas cosas. Pero ser un novato en Verilog no puedo continuar. Realmente me encantaría que alguien me indicara un enlace útil.

// pixel processor datapath unit//
module PPDU(err_0,htpv,err_1,err_2,err_3,err_4,pv);
output [7:0]err_0;
output htpv;
input [7:0]err_1,err_2,err_3,err_4,pv;
wire [9:0]cpv,cpv_round,e_av;
parameter w1=2,w2=8,w3=4,w4=2;
parameter threshold =128;
assign e_av=(w1*err_1+w2*err_2+w3*err_3+w4*err_4)>>4;
assign cpv=pv+e_av;
assign cpv_round=(cpv<threshold)?0:255;
assign htpv=(cpv_round==0)?0:1;
assign err_0=cpv-cpv_round;
endmodule

module image_converter (pixel_1,pixel_2,pixel_3,pixel_4,pixel_5,pixel_6,pixel_7,pixel_8,pixel_9,
   pixel_10,pixel_11,pixel_12,pixel_13,pixel_14,pixel_15,pixel_16,pixel_17,
   pixel_18,pixel_19,pixel_20,pixel_21,pixel_22,pixel_23,pixel_24,pixel_25,
   pixel_26,pixel_27,pixel_28,pixel_29,pixel_30,pixel_31,pixel_32,pixel_33,
   pixel_34,pixel_35,pixel_36,pixel_37,pixel_38,pixel_39,pixel_40,pixel_41,
   pixel_42,pixel_43,pixel_44,pixel_45,pixel_46,pixel_47,pixel_48,htpv_1,
      htpv_2,htpv_3,htpv_4,htpv_5,htpv_6
      );
 input [7:0]pixel_1,pixel_2,…..,pixel_47,pixel_48;
 output [1:8]htpv_1,htpv_2,htpv_3,htpv_4,htpv_5,htpv_6;
 wire [7:0]err_1,err_2,……., err_47,err_48;
 PPDU a0(err_1,htpv_1[1],8'b00,8'b00,8'b00,8'b00,pixel_1);
 ...
 PPDU a7(err_8,htpv_1[8],err_7,8'b00,8'b00,8'b00,pixel_8);                       
 PPDU b1(err_9,htpv_2[1],8'b00,8'b00,err_1,err_2,pixel_9);
 ...     PPDU b8(err_16,htpv_2[8],err_15,err_7,err_8,8'b00,pixel_16);
 PPDU c1(err_17,htpv_3[1],8'b00,8'b00,err_9,err_2,pixel_17);
 ….
 PPDU c8(err_24,htpv_3[8],err_23,err_15,err_16,8'b00,pixel_24);
 PPDU d1(err_25,htpv_4[1],8'b00,8'b00,err_17,err_18,pixel_25);
 ….
 PPDU d8(err_32,htpv_4[8],err_31,err_23,err_24,8'b00,pixel_32);
 PPDU e1(err_33,htpv_5[1],8'b00,8'b00,err_25,err_26,pixel_33);
 ….
 PPDU e8(err_40,htpv_5[8],err_39,err_31,err_32,8'b00,pixel_40);
 PPDU fi(err_41,htpv_6[1],8'b00,8'b00,err_33,err_34,pixel_41);
 ….
 PPDU f8(err_48,htpv_6[8],err_47,err_39,err_40,8'b00,pixel_40);  
 end
 endmodule
    
pregunta Saad Rafey

1 respuesta

3

Comience leyendo sobre "generar"

"Generar" te permitirá crear muchas copias de un módulo con parámetros sutilmente diferentes. Puede ser un poco complicado pero es mejor que crear una docena de copias de algo.

Sin embargo, eso no es lo que realmente quieres hacer aquí, porque si creas un millón de algo que te quedará sin espacio.

Lo que quieres es un contador:

reg [31:0] var;
always @(posedge clk) begin
   if (var < limit) var <= var + 1;
   else var <= 0;
end

Eso corresponde aproximadamente a un bucle 'for' que le dará un valor incremental de 'var' en cada ciclo de reloj, hasta que alcance el límite en el que comenzará nuevamente desde cero.

Encontrará todo más fácil si almacena sus píxeles en una matriz (o RAM), y difumina un píxel por ciclo. Luego tomará un millón de ciclos de reloj para hacer su tramado, pero su circuito será pequeño.

Recuerda, en Verilog todo sucede en paralelo, y todo se desvía para siempre.

    
respondido por el pjc50

Lea otras preguntas en las etiquetas