2
\$\begingroup\$

I am explaining my question in detail now as I am realizing that I did not explain my question well.

I am a beginner in Verilog. To learn the language I am writing some sample applications.
At present I am writing Verilog code to convert 8 bit BMP image to half tone BMP image using Floyd-Steinberg algorithm. Basically I am converting 8 bit pixels into 1 bit using the said algorithm.

I found the sample code for this algorithm in the book Advanced Digital Design with the Verilog HDL - Michael D. Ciletti on page number 555. I have successfully simulated the design in ModelSim.

The problem is the example is given for an image of size 6 x 8, but to learn and practice I am trying to convert this code for different formats and sizes. As a first goal I am trying to modify this code (which I have already understood well) to work for images of size 1000 x 1000. Since the example was for only 48 pixels (6 x 8), it was easier to write the instructions inside the module manually, as shown in the code given below. But in case I have 10,00000 pixels (1000 x 1000) how do I change the code. I cannot write such equations:

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

10,00000 manually (kindly see the code given below).

I guess there has to be some way for automating this job.

In C I can use for loops for autoamting many things. But being a novice in Verilog I am unable to proceed. I will really aprecaite if somebody can point me to a useful link.

// 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
\$\endgroup\$
9
  • 3
    \$\begingroup\$ Do you want to do all of the pixels at once? You could pipeline it and do one per clock (this is necessary if your pixels are stored in a RAM). Otherwise, look at the 'generate' keyword. \$\endgroup\$
    – pjc50
    Jan 15, 2013 at 13:09
  • 1
    \$\begingroup\$ The question is quite clear : he has solved the problem for one pixel, but can't see how to replicate the solution for all pixels. If I were to answer, I'd use VHDL, so it wouldn't help him much. Hopefully the Verilog users here will step in. \$\endgroup\$
    – user16324
    Jan 15, 2013 at 13:58
  • 1
    \$\begingroup\$ Just my $0.02: This is electronics just as much as microcontroller programming is: Neither would have been considered electronics some years ago, when we EEs essentially played analog, and let the softweenies play the coding games. \$\endgroup\$ Jan 15, 2013 at 15:40
  • 3
    \$\begingroup\$ Since the FPGA/ASIC stackexchange was deemed to be a duplicate of this one, "how do I do X in Verilog" questions are either on topic here or nowhere.. \$\endgroup\$
    – pjc50
    Jan 15, 2013 at 16:15
  • 1
    \$\begingroup\$ This is cross posted at stackoverflow.com \$\endgroup\$
    – Tim
    Jan 16, 2013 at 7:30

1 Answer 1

3
\$\begingroup\$

Start by reading about "generate"

"Generate" will let you create lots of copies of a module with subtly different parameters. It can be a bit fiddly but it's better than creating a dozen copies of something.

However, that's not what you actually want to do here, because if you create a million copies of something you will run out of space.

What you want is a counter:

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

That roughly corresponds to a 'for' loop which will give you an incrementing value of 'var' on each clock cycle, until it hits the limit at which point it will start again from zero.

You'll find the whole thing easier if you store your pixels in an array (or RAM), and dither one pixel per cycle. Then it will take a million clock cycles to do your dithering, but your circuit will be small.

Remember, in Verilog everything happens in parallel, and everything loops forever.

\$\endgroup\$
2
  • \$\begingroup\$ I am confused how to implement it using generate loop. I am giving three consecutive lines from above given code in which I am having problem. ............................. PPDU a7(err_8,htpv_1[8],err_7,8'b0,8'b0,8'b0,pixel_8); PPDU b1(err_9,htpv_2[1],8'b0,8'b0,err_1,err_2,pixel_9); PPDU b2(err_10,htpv_2[2],err_9,err_1,err_2,err_3,pixel_10);........ In first line PPDU a7 after err_7 8'b0, 8'b0, 8'b0, but in the second line PPDU b1 last two 8'b0 are replaced by err_1,_2 and in the third line all the 8'b0 are replaced by err_9,_1,_2,_3. ...I unable to implement it using generate loop. \$\endgroup\$
    – Saad Rafey
    Jan 16, 2013 at 7:11
  • \$\begingroup\$ @SaadRafey I think you might have to change the way you are implementing the algorithm. A counter as suggested may not directly work in your case. \$\endgroup\$
    – gpuguy
    Jan 16, 2013 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.