Site Logo
Find in
This is TikiWiki 1.9.7 -Sirius- © 2002–2006 by the Tiki community Thu 09 of Sep, 2010 [05:42 UTC]
Login
[ register | I forgot my password ]
Menu [hide]
 Home
 Contact us
 Stats
 Categories
 Calendar
Toggle  Wiki
 Wiki Home
 Last Changes
 Dump
 Rankings
 List pages
 Orphan pages
 Sandbox
 Print
Toggle  Blogs
 List blogs
 Rankings

Verilog Lesson 3

tag correction
3D browser print PDF
English
Verilog Lesson 3 by T. Miller

Before we go further, I figure we should have a short quiz.

Explain this code in detail:
module whatsit(a, b, d, c);
input [3:0] a, b;
input d;
output [3:0] c;
wire [3:0] e, f;
assign e = a & b;
assign f = a + b;
assign c = d ? e : f;
endmodule

Also, some information is being lost. Identify it.

Ok, on to the lesson. Continuous assignments like what we saw are powerful but limiting in their forms of expression. To augment is expressiveness, Verilog has what are called behavioral blocks or "always" blocks. Tonight, we'll just cover a handful of things that you can do. Behavioral blocks look a lot more like C programming, and they allow you to express algorithms in a way that looks sequential (even when it's not in hardware). In fact, we'll see later how to express sequential logic (logic with registers and clock signals).

The syntax for a behavioral block is:
always @(sensitivity_list) <statements>

The sensitivity list must include every signal that is an input to anything expressed in the behavioral block. Doing this incorrectly won't affect synthesis, but it will affect simulation. The sensitivity list is a sequence of inputs separated by the keyword "or":
always @(a or b or d) <statements>

Now, signals on the right-hand-side of an expression can be of either type wire or of type reg. But the left-hand-side must how always be of type reg:
reg [3:0] c;
always @(a or b or d) begin
   c = <something using the inputs>;
end

Basically the difference between reg and wire is that reg is the type on the lhs of an expression in a behavioral block. You'd think they'd make 'reg' mean a register (flipflops), but not necessarily, and this is a point of confusion for beginners.

The assignments we're using in this lesson, using the "=" operator, are called "blocking" assignments. For simulation, that means that the expression is computed and the signal is assigned its value immediately so that the result is available for subsequent statements. We'll explain non-blocking assignments next time. As a rule of thumb, we use blocking assignments in combinatorial logic and non-blocking assignments in sequential logic, and we avoid mixing them up.

You can express chains of operations to be done with all sorts of dependencies between them, and the synthesizer will just combine them together, perhaps creating rather long combinatorial chains. For instance:
wire [3:0] a, b, c, d, e;
reg [3:0] f, g, h, j;
always @(a or b or c or d or e) begin
   f = a+b;
   g = f & c;
   h = g | d;
   j = h - e;
end

And this is equivalent to:
reg [3:0] j = (((a+b) & c) | d) - e;

f, g, and h may or may not exist as identifiable signals once the synthesizer is done with this, depending on whether or not some other piece of logic uses them. If, for instance, f is never used anywhere else, the synthesizer will give you a warning, saying that it is assigned but not used. That's okay, because its result is used as part of the bigger expression. All it means is that nothing in the netlist is going to be named "f".

In behavioral blocks, we can now do some more interesting things, like if-statements, case-statements, loops, etc. For instance, to express the quiz problem behaviorally, we can do this:
reg [3:0] c;
always @(a or b or d) begin
   c = d ? (a & b) : (a + b);
end

Or we can do it this way:
reg [3:0] c;
always @(a or b or d) begin
   if (d) begin
       c = a & b;
   end else begin
       c = a + b;
   end
end

In the place of 'd', you can have any expression. Zero means false and any non-zero value is true.

Case statements are just like switch statements in C. They're a great way to express multiplexers over more than two inputs or to select between different actions.

The basic syntax is:
case (selector)
    option1: <statement>;
    option2: <statement>;
    default:  <if nothing else statement>;  // optional
endcase

Here's an example:
wire [1:0] option;
wire [7:0] a, b, c, d;
reg [7:0] e;
always @(a or b or c or d or option) begin
   case (option)
       0: e = a;
       1: e = b;
       2: e = c;
       3: e = d;
   endcase
end

This will synthesize to eight 4-to-1 muxes.

You can also do goofy things like this with case statements:
wire [3:0] x;
always @(...) begin
   case (1'b1)
       x[0]: <something1>;
       x[1]: <something2>;
       x[2]: <something3>;
       x[3]: <something4>;
   endcase
end

Logically speaking (and literally in simulation), the case statement walks down the list of cases and executes the first one that matches. So here, if the lowest 1-bit of x is bit 2, then something3 is the statement that will get executed (or selected by the logic).

The latter is great for 1-hot encoded state machines which we'll also have to cover another time.

Ok, we've seen case and if. How about a loop. For synthesis, a loop must have a fixed number of iterations, otherwise, it can't map to a fixed amount of logic. A good example perhaps is a priority encoder. Given a bit vector, we would like to know the highest bit that is set, and we'd like that number to be the output of our block.
wire [15:0] in_data;
reg [3:0] high_bit;
reg valid;
integer i;
always @(in_data) begin
   valid = 0;    // Assume invalid by default
   high_bit = 0;   // Set this to something by default to avoid inferring a latch
   for (i=0; i<16; i=i+1) begin
       if (in_data[i]) begin
           valid = 1;  // We found one, so set it valid
           high_bit = i;  // and note the number
       end
   end
end

Chew on that for a moment before going on. It's looping over the bits from the bottom up. Whenever it hits a bit, it notes the position. When the loop has completed, high_bit will contain the index of the highest 1 bit encountered. If you wanted the lowest bit, you would do it this way:
always @(in_data) begin
   valid = 0;    // Assume invalid by default
   high_bit = 0;   // Set this to something by default to avoid inferring a latch
   for (i=15; i>=0; i=i-1) begin
       if (in_data[i]) begin
           valid = 1;  // We found one, so set it valid
           high_bit = i;  // and note the number
       end
   end
end

One reason I use an integer for the loop count is just so loops like this will work. regs and wires are unsigned numbers. Only integer is signed. So when the loop counter rolls around from 0 to -1, only the integer will represent it correctly and have the >=0 comparison yield false.

Ok, I'm going to go out on a limb here. The next thing I'm going to show you is doable with everything we've covered up to this point, but it's really advanced for only being the third lesson. I suggest, therefore, that people pick it apart or perhaps suggest that it not be included in official lessons if it's a problem.

This list is dedicated to graphics, and so I'd like to show you how we can now do something that is fundamental to 2D graphics, which is to apply a planemask and a raster operation to two pixel values. One value is the destination pixel that was read from the target location in the framebuffer. The other value is the source pixel that was generated from drawing engine logic. OGA does this logic around about where it also does alpha blending between source and dest.

Here are your two input pixel values:
wire [31:0] src;
wire [31:0] dst;

And here's your planemask. The planemask is used to select which src bits are written out and which dst bits are preserved. A 1 in the planemask means to write the src bit and a 0 means to leave the dst bit alone.
wire [31:0] pmsk;

Now, let's combine the pixels:
reg [31:0] result;
integer i;
always @(src or dst or pmsk) begin
   for (i=0; i<32; i=i+1) begin
       if (pmsk[i]) begin
           // 1 means to use the src
           result[i] = src[i];
       end else begin
           // 0 means to keep the dst
           result[i] = dst[i];
       end
   end
end

Here's a functionally equivalent way to express this (but it may or may not produce identical logic):
wire [31:0] result = (pmsk & src) | (~pmsk & dst);

Next, there's the raster-op (ROP). Given any two bits, there are 16 ways to combine them. These include the basics like AND, OR, and XOR, but also things like src-only (copy), dst-only (no-op), invert (~dst), copy-invert (~src), and the degenerate cases clear (0) and set (all 1 bits).

Since there are 16 ROPs, we can use a 4-bit number to express them. Have a look in "/usr/include/X11/X.h" and search for GXcopy. You'll find names for all 16 rops and their numbers.

The easiest way to express this in hardware is to concatenate the two bits together into a 2-bit number and use that to mux amongst the four ROP bits. If you don't see this right away, don't fret. I didn't either. I suggest you play about a bit with ROP numbers and input bit values and see it in action. Also, we're using the mux a bit strangely. Usually, we have inputs to the mux and some number to select amongst them on the select input. In this case, the "inputs" are a constant, and the pixel bits are being used as the select inputs. Here's the behavioral logic for that:
wire src_bit, dst_bit;
wire [3:0] rop;
reg result_bit;
always @(src_bit or dst_bit or rop) begin
   case ({src_bit, dst_bit})
       0: result = rop[0];
       1: result = rop[1];
       2: result = rop[2];
       3: result = rop[3];
   endcase
end

You may have noticed a pattern. In fact, we can use a bit-select to express the same thing more concisely:
wire result_bit = rop[{src_bit, dst_bit}];

Let's try an example. GXxor is function number 6, which in binary is 4'b0110.

If both src_bit and dst_bit are 0's, we want the exclusive or to be 0,and so we see that rop[0] is in fact 0.
If src_bit=0 and dst_bit=1, we want the result to be 1. Looking at rop[1], we do in fact find a 1.
If src_bit=1 and dst_bit=0, we want the result to be 1. Looking at rop[2], we find a 1, as expected.
Finally, if they're both 1's, the xor needs to be zero, and we find rop[3] to be 0.

Now that we have that out of the way, let's look at how we can combine ROPs and planemasks and pixels together in one chunk of logic:
module mask_and_rop(
   src, dst,
   pmask, rop,
   result);

input [31:0] src, dst, pmask;
input [3:0] rop;
output [31:0] result;

reg [31:0] result;  // override wireness, making result a reg

integer i;  // loop counter
always @(src or dst or pmask or rop) begin
   // Loop over all bits in the pixels
   for (i=0; i<32; i=i+1) begin
       if (pmask[i]) begin
           // If pmask bit is true, we combine src and dst
           // based on ROP
           result[i] = rop[{src[i], dst[i]}];
       end else begin
           // Otherwise, we preserve the dst bit
           result[i] = dst[i];
       end
   end
end

endmodule

We could also make that loop a little more concise like this:
always @(src or dst or pmask or rop) begin
   for (i=0; i<32; i=i+1) begin
       result[i] = pmask[i] ? rop[{src[i], dst[i]}] : dst[i];
   end
end

For completeness, Windows GDI defines something called a ROP4. A ROP4 combined four things:

  • A source pixel (color)
  • A dest pixel (color)
  • A pattern pixel (color)
  • A mask pixel (monochrome)

Typically, the pattern is 8x8 and logically repeated over the area of the drawing surface. The mask is typically 32x32 (IIRC), and it's also repeated. (Windows doesn't define a planemask, but we have it in the hardware for X11.)

Here's the logic to combine these together:
module src_and_dst_and_patt_and_mask_and_planemask_and_rop(
   src, dst, patt, mask,
   planemask, rop,
   result);

input [31:0] src, dst, patt, planemask;
input mask;
input [15:0] rop;   // Notice the 16-bit ROP4
output [31:0] result;

reg [31:0] result;  // override wireness, making result a reg

integer i;  // loop counter
always @(src or dst or pmask or rop) begin
   // Loop over all bits in the pixels
   for (i=0; i<32; i=i+1) begin
       if (planemask[i]) begin
           // If planemask bit is true, we combine src and dst
           // based on ROP
           result[i] = rop[{mask, patt[i], src[i], dst[i]}];
       end else begin
           // Otherwise, we preserve the dst bit
           result[i] = dst[i];
       end
   end
end

endmodule

Turns out to be painfully simple in the end.biggrin

Created by: hamish last modification: Wednesday 19 of December, 2007 [16:43:33 UTC] by vininim


source
history
similar
10 comments

Posted messages

Top Hide all
author message
Tarun004
OGP- Great Work
on: Thu 05 of Aug, 2010 [15:08 UTC] score: 0.00


This post is exactly what I am interested. we need some more good information. Please add more good information that would help others in such good way..Open graphics project is very nice to see in all scenario for all phase of project creation.
However I am form Programming field but there are a lot of things which I have to understand too.Kidney stones treatmentHome Automation |DUI Lawyer | | government jobs | Freshers Jobs


author message
hidebr
Re: OGP- Great Work
on: Sun 22 of Aug, 2010 [13:08 UTC] score: 0.00
>
>
> This post is exactly what I am interested. we need some more good information. Please add more good information that would help others in such good way..Open graphics project is very nice to see in all scenario for all phase of project creation.
> However I am form Programming field but there are a lot of things which I have to understand too.and criação de sites and desenvolvimento de site and Unhas and Esmaltes and Tokio Hotel and Tokio Hotel Magazine and Escola de Surf and Web site e Home page and Portal and Loja Virtual and E-Commerce and Hotsite em Flash and Integração com Cielo and Configuração Google-Mini and Sistemas Web and Sistemas CRM e ERP and Camisetas and Tshirt


author message
aaddad
cheap ugg boots
on: Wed 18 of Aug, 2010 [11:02 UTC] score: 0.00
http://www.salesuggsboots.com/ugg-adirondack-ii-sku-boots-otter-p-365.html|ugg adirondack


author message
bradblack
Re: OGP- Great Work
on: Sat 07 of Aug, 2010 [07:50 UTC] score: 0.00
Please add more good information that would help others in such good way..Open graphics project is very nice to see in all scenario for all phase of project creation. ab ripper x workout list | side ab workouts for men | ab ripper x exercise list | effective ab exercises for men | side abs exercises for men


author message
vuitton
Re: Re: OGP- Great Work
on: Wed 11 of Aug, 2010 [22:05 UTC] score: 0.00
biggrinVery informative content.so useful love it so muchcool
louis vuitton thames
n51110
lv handbags
lol


author message
Routers-home
Re: Re: Re: OGP- Great Work
on: Thu 12 of Aug, 2010 [14:19 UTC] score: 0.00
very good article , i don't used this language before , look interesting .
pen graphics project is very nice to see in all scenario for all phase of project creation.
I will start learning it once many great tutos are available
keep working
linksys e1000 review|linksys e2000 review|router signal| router wireless reviews


author message
matt44
answer
on: Mon 16 of Aug, 2010 [16:49 UTC] score: 0.00
I am so satisfied that I have found this your post because I have been searching for some information about these lessons almost two hours. You helped me a lot indeed and reading this your article I have found many new and useful information about this subject. Well, I will definitely bookmark your website and wait for other useful and informative posts like this one in the future. Regards, Matt Rickson from Rhode Island


author message
Gwyneth259
Great
on: Sat 21 of Aug, 2010 [19:05 UTC] score: 0.00
This is a great lesson. I am learning so much in these series of lessons. Thanks so much.
Cheap Auto Insurance


author message
Vicky49e
Great lesson
on: Wed 25 of Aug, 2010 [16:07 UTC] score: 0.00
This is a really great lesson that I appreciate. I have learned so much from this great website. I really do appreciate everything that you guys have done for me.

Thanks Victoria Canard
Amish Furniture


author message
duke
great lesson
on: Thu 02 of Sep, 2010 [06:37 UTC] score: 0.00
Nicely done, thanks for the explanation.

kidney infection symptoms
make money online
cure panic attacks
shimano sahara



Page: 1/1
1 

RSS Wiki RSS Blogs
Übersetzen Sie diese Seite ins Deutsche
Traduzca esta paginación a español
Traduisez cette page en français
Tradurre questa pagina in italiano
Traduza esta página em portuguêses
翻译这页成汉语 (CN)
日本語にこのページを翻訳しなさい (Nihongo)
한국인으로 이 페이지를 번역하십시요 (Hangul)
[ Execution time: 1.00 secs ]   [ Memory usage: 7.52MB ]   [ 129 database queries used ]   [ GZIP Disabled ]   [ Server load: 0.26 ]
How buy cialis 20mg online
kamagra 100mg How download mp3 music online
sex dating