FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > Verilog

Verilog comp.lang.verilog newsgroup / usenet

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 07-18-2004, 10:35 AM
Frank Buss
Guest
 
Posts: n/a
Default my first Verilog program

I'm learning Verilog and have some questions, because I have no
experience with HDL and not much with hardware design. Below is my
first Verilog program, which works with the nice Spartan3 starter
kit from Xilinx. Perhaps you can take a look at it and give me some
hints how I can improve it and where are possible bugs.

Some specific questions:

- how can I latch the vga output signals on falling clock edge without
another reg-set? I assume somthing with "wire", but I don't know

- the state machine for the VGA signal generation looks like it can be
simplified

- how can I do "meta"-programming? For example the handling for
led0Power to led7Power is all the same, so I need something like a loop,
but how do I declare the variables as arrays and access them?


module test(
clk, led, segment, digit,
VGA_Red, VGA_Green, VGA_Blue, VGA_HSYNCH_N, VGA_VSYNCH_N);

input clk;

output [7:0] led;
output [7:0] segment;
output [3:0] digit;

assign segment[0] = 0;
assign segment[1] = 0;
assign segment[2] = 0;
assign segment[3] = 0;
assign segment[4] = 0;
assign segment[5] = 0;
assign segment[6] = 0;
assign segment[7] = 0;
assign digit[0] = 1;
assign digit[1] = 1;
assign digit[2] = 1;
assign digit[3] = 1;

//
// VGA video pattern generator
//

/* VGA timings:
clocks per line:
1. HSync low pulse for 96 clocks
2. back porch for 48 clocks
3. data for 640 clocks
4. front porch for 16 clocks

VSync timing per picture (800 clocks = 1 line):
1. VSync low pulse for 2 lines
2. back porch for 29 lines
3. data for 480 lines
4. front porch for 10 lines
*/

`define LINE_HSYNC_LOW 0
`define LINE_BACK_PORCH 1
`define LINE_DATA 2
`define LINE_FRONT_PORCH 3

`define IMAGE_VSYNC_LOW 0
`define IMAGE_BACK_PORCH 1
`define IMAGE_DATA 2
`define IMAGE_FRONT_PORCH 3

output VGA_Red;
output VGA_Green;
output VGA_Blue;
output VGA_HSYNCH_N;
output VGA_VSYNCH_N;

reg rVGA_Red = 0;
reg rVGA_Green = 0;
reg rVGA_Blue = 0;
reg rVGA_HSYNCH_N = 0;
reg rVGA_VSYNCH_N = 0;

reg latchVGA_Red = 0;
reg latchVGA_Green = 0;
reg latchVGA_Blue = 0;
reg latchVGA_HSYNCH_N = 0;
reg latchVGA_VSYNCH_N = 0;

assign VGA_Red = latchVGA_Red;
assign VGA_Green = latchVGA_Green;
assign VGA_Blue = latchVGA_Blue;
assign VGA_HSYNCH_N = latchVGA_HSYNCH_N;
assign VGA_VSYNCH_N = latchVGA_VSYNCH_N;

reg [2:0] lineState = 0;
reg [2:0] imageState = 0;
reg [10:0] pixelCounter = 0;
reg [10:0] lineCounter = 0;
reg devide2 = 0;

always @(posedge clk) begin
devide2 <= ~devide2;
if (devide2) begin
// check line
case (lineState)
`LINE_HSYNC_LOW: begin
if (pixelCounter == 96) begin
pixelCounter <= 0;
lineState = `LINE_BACK_PORCH;
rVGA_HSYNCH_N <= 1;
end else pixelCounter <= pixelCounter + 1;
end
`LINE_BACK_PORCH: begin
if (pixelCounter == 48) begin
pixelCounter <= 0;
lineState = `LINE_DATA;
end else pixelCounter <= pixelCounter + 1;
end
`LINE_DATA: begin
if (lineCounter < 480 && imageState == `IMAGE_DATA) begin
rVGA_Red <= pixelCounter[4];
rVGA_Green <= pixelCounter[5];
rVGA_Blue <= pixelCounter[6];
end else begin
rVGA_Red <= 0;
rVGA_Green <= 0;
rVGA_Blue <= 0;
end
if (pixelCounter == 640) begin
pixelCounter <= 0;
lineState = `LINE_FRONT_PORCH;
end else pixelCounter <= pixelCounter + 1;
end
`LINE_FRONT_PORCH: begin
if (pixelCounter == 16) begin
pixelCounter <= 0;
lineState = `LINE_HSYNC_LOW;
rVGA_HSYNCH_N <= 0;

// check image
case (imageState)
`IMAGE_VSYNC_LOW: begin
if (lineCounter == 2) begin
lineCounter <= 0;
imageState = `IMAGE_BACK_PORCH;
rVGA_VSYNCH_N <= 1;
end else lineCounter <= lineCounter + 1;
end
`IMAGE_BACK_PORCH: begin
if (lineCounter == 29) begin
lineCounter <= 0;
imageState = `IMAGE_DATA;
end else lineCounter <= lineCounter + 1;
end
`IMAGE_DATA: begin
if (lineCounter == 480) begin
lineCounter <= 0;
imageState = `IMAGE_FRONT_PORCH;
end else lineCounter <= lineCounter + 1;
end
`IMAGE_FRONT_PORCH: begin
if (lineCounter == 16) begin
lineCounter <= 0;
imageState = `IMAGE_VSYNC_LOW;
rVGA_VSYNCH_N <= 0;
end else lineCounter <= lineCounter + 1;
end
default:
imageState = `IMAGE_VSYNC_LOW;
endcase
end else pixelCounter <= pixelCounter + 1;
end
default:
lineState = `LINE_HSYNC_LOW;
endcase
end
end

always @(negedge clk) begin
latchVGA_Red <= rVGA_Red;
latchVGA_Green <= rVGA_Green;
latchVGA_Blue <= rVGA_Blue;
latchVGA_HSYNCH_N <= rVGA_HSYNCH_N;
latchVGA_VSYNCH_N <= rVGA_VSYNCH_N;
end


//
// knight rider like LED scroll
//
reg [16:0] devide2500 = 0; // 50 MHz / 1000 = 50 kHz
reg [16:0] devideLed = 0;
reg [16:0] scrollLedCounter = 0;
reg [4:0] scrollLed = 0;

reg led0 = 0;
assign led[0] = led0;
reg [7:0] led0Power = 0;
reg [7:0] led0Counter = 0;

reg led1 = 0;
assign led[1] = led1;
reg [7:0] led1Power = 0;
reg [7:0] led1Counter = 0;

reg led2 = 0;
assign led[2] = led2;
reg [7:0] led2Power = 0;
reg [7:0] led2Counter = 0;

reg led3 = 0;
assign led[3] = led3;
reg [7:0] led3Power = 0;
reg [7:0] led3Counter = 0;

reg led4 = 0;
assign led[4] = led4;
reg [7:0] led4Power = 0;
reg [7:0] led4Counter = 0;

reg led5 = 0;
assign led[5] = led5;
reg [7:0] led5Power = 0;
reg [7:0] led5Counter = 0;

reg led6 = 0;
assign led[6] = led6;
reg [7:0] led6Power = 0;
reg [7:0] led6Counter = 0;

reg led7 = 0;
assign led[7] = led7;
reg [7:0] led7Power = 0;
reg [7:0] led7Counter = 0;

always @(posedge clk) begin
if (devide2500 == 2500) begin
devide2500 = 0;

if (led0Power > led0Counter) led0 <= 1; else led0 <= 0;
if (led0Counter == 255) led0Counter <= 0; else led0Counter <= led0Counter + 1;

if (led1Power > led1Counter) led1 <= 1; else led1 <= 0;
if (led1Counter == 255) led1Counter <= 0; else led1Counter <= led1Counter + 1;

if (led2Power > led2Counter) led2 <= 1; else led2 <= 0;
if (led2Counter == 255) led2Counter <= 0; else led2Counter <= led2Counter + 1;

if (led3Power > led3Counter) led3 <= 1; else led3 <= 0;
if (led3Counter == 255) led3Counter <= 0; else led3Counter <= led3Counter + 1;

if (led4Power > led4Counter) led4 <= 1; else led4 <= 0;
if (led4Counter == 255) led4Counter <= 0; else led4Counter <= led4Counter + 1;

if (led5Power > led5Counter) led5 <= 1; else led5 <= 0;
if (led5Counter == 255) led5Counter <= 0; else led5Counter <= led5Counter + 1;

if (led6Power > led6Counter) led6 <= 1; else led6 <= 0;
if (led6Counter == 255) led6Counter <= 0; else led6Counter <= led6Counter + 1;

if (led7Power > led7Counter) led7 <= 1; else led7 <= 0;
if (led7Counter == 255) led7Counter <= 0; else led7Counter <= led7Counter + 1;

if (devideLed == 60) begin
devideLed <= 0;
if (led0Power > 0) led0Power <= led0Power * 255 / 256;
if (led1Power > 0) led1Power <= led1Power * 255 / 256;
if (led2Power > 0) led2Power <= led2Power * 255 / 256;
if (led3Power > 0) led3Power <= led3Power * 255 / 256;
if (led4Power > 0) led4Power <= led4Power * 255 / 256;
if (led5Power > 0) led5Power <= led5Power * 255 / 256;
if (led6Power > 0) led6Power <= led6Power * 255 / 256;
if (led7Power > 0) led7Power <= led7Power * 255 / 256;

if (scrollLedCounter == 60) begin
scrollLedCounter <= 0;
scrollLed <= scrollLed + 1;
case (scrollLed)
0: led0Power <= 255;
1: led1Power <= 255;
2: led2Power <= 255;
3: led3Power <= 255;
4: led4Power <= 255;
5: led5Power <= 255;
6: led6Power <= 255;
7: led7Power <= 255;
8: led7Power <= 255;
9: led6Power <= 255;
10: led5Power <= 255;
11: led4Power <= 255;
12: led3Power <= 255;
13: led2Power <= 255;
14: led1Power <= 255;
15: begin led0Power <= 255; scrollLed <= 0; end
endcase
end else begin
scrollLedCounter <= scrollLedCounter + 1;
end

end else begin
devideLed <= devideLed + 1;

end

end else devide2500 = devide2500 + 1;
end

endmodule


--
Frank Buß, [email protected]
http://www.frank-buss.de, http://www.it4-systems.de
Reply With Quote
  #2 (permalink)  
Old 07-19-2004, 10:23 PM
Swapnajit Mittra
Guest
 
Posts: n/a
Default Re: my first Verilog program

Frank Buss <[email protected]> wrote in message news:<[email protected]>...
> I'm learning Verilog and have some questions, because I have no
> experience with HDL and not much with hardware design. Below is my
> first Verilog program, which works with the nice Spartan3 starter
> kit from Xilinx. Perhaps you can take a look at it and give me some
> hints how I can improve it and where are possible bugs.


Frank,

Welcome to Verilog and hardware design. See below for answers
to your questions.
>
> Some specific questions:
>
> - how can I latch the vga output signals on falling clock edge without
> another reg-set? I assume somthing with "wire", but I don't know.


Probably I do not understand your question but it seems to me you
are already doing that.

always @(negedge clk) begin
latchVGA_Red <= rVGA_Red;
latchVGA_Green <= rVGA_Green;
latchVGA_Blue <= rVGA_Blue;
latchVGA_HSYNCH_N <= rVGA_HSYNCH_N;
latchVGA_VSYNCH_N <= rVGA_VSYNCH_N;
end

>
> - the state machine for the VGA signal generation looks like it can be
> simplified?


This is a holy area that has many sects with various ideas
(and ideologies). Here is mine. In general, I tend to divide
a module in three parts:

1. A current state generator for the state machine:

This is identical in all designs.

always @(posedge clk)
if (reset) // synchronous reset
current_state <= IDLE;
else
current_satet <= next_state;

I would suggest, use a one hot state machine that will
reduce your coding effort (you can use
'if (current_state[STATEn_BIT])', rather than
'if (current_state == STATEn)'), if not help you meet
your timing goal.

2. A *combinatorial* state machine:

This is the logic that will assign the next_state
from current states and the inputs AND NOTHING ELSE.
Typically, a state inside the state machine will look
like:

always @* begin
next_state = current_state;
...
case (1'b1)
current_state[STATEn_BIT]: begin
if (...)
next_state = STATEm;
else
next_state = STATEp;
end
...
endcase

3. All other flops and combinatorial logic:

This is where rest of the logic goes. Organize the logic
according to their functions. Keep the logic that are related
in the same palce. This will help you debug later.

>
> - how can I do "meta"-programming? For example the handling for
> led0Power to led7Power is all the same, so I need something like a loop,
> but how do I declare the variables as arrays and access them?


If the behavior for all ledxPower are identical *all the time*
(I did not explore your logic enough to see if they are), then
you do not need to write 8 of them - just define one and then
fan the output out.

If they are logically identical with different inputs, then
define one module that has the logic for one of the ledxPower
and then instatiates it 8 times.

You might want to take a look at the following site for
some example design:

http://pancham.sourceforge.com

Hope this helps.
- Swapnajit.

--
SystemVerilog, Verilog, PLI and all the good stuffs
Project VeriPage::: http://www.project-veripage.com
Reply With Quote
  #3 (permalink)  
Old 07-20-2004, 07:16 AM
Blackie Beard
Guest
 
Posts: n/a
Default Re: my first Verilog program

It would be a good idea to use an asynchronous reset in
the design. Initial conditions and all that.

always @(posedge clk or negedge rstn)
if(~rstn)
my_reg <= 1'b0;
else
my_reg <= my_nextreg_wire_value;

If you only latch on posedge of clk, your design will
be more portable later. At least that's the way it
was when I was learning. Don't know about nowadays.

BB


"Frank Buss" <[email protected]> wrote in message
news:[email protected]
> I'm learning Verilog and have some questions, because I have no
> experience with HDL and not much with hardware design. Below is my
> first Verilog program, which works with the nice Spartan3 starter
> kit from Xilinx. Perhaps you can take a look at it and give me some
> hints how I can improve it and where are possible bugs.
>
> Some specific questions:
>
> - how can I latch the vga output signals on falling clock edge without
> another reg-set? I assume somthing with "wire", but I don't know
>
> - the state machine for the VGA signal generation looks like it can be
> simplified
>
> - how can I do "meta"-programming? For example the handling for
> led0Power to led7Power is all the same, so I need something like a loop,
> but how do I declare the variables as arrays and access them?
>
>
> module test(
> clk, led, segment, digit,
> VGA_Red, VGA_Green, VGA_Blue, VGA_HSYNCH_N, VGA_VSYNCH_N);
>
> input clk;
>
> output [7:0] led;
> output [7:0] segment;
> output [3:0] digit;
>
> assign segment[0] = 0;
> assign segment[1] = 0;
> assign segment[2] = 0;
> assign segment[3] = 0;
> assign segment[4] = 0;
> assign segment[5] = 0;
> assign segment[6] = 0;
> assign segment[7] = 0;
> assign digit[0] = 1;
> assign digit[1] = 1;
> assign digit[2] = 1;
> assign digit[3] = 1;
>
> //
> // VGA video pattern generator
> //
>
> /* VGA timings:
> clocks per line:
> 1. HSync low pulse for 96 clocks
> 2. back porch for 48 clocks
> 3. data for 640 clocks
> 4. front porch for 16 clocks
>
> VSync timing per picture (800 clocks = 1 line):
> 1. VSync low pulse for 2 lines
> 2. back porch for 29 lines
> 3. data for 480 lines
> 4. front porch for 10 lines
> */
>
> `define LINE_HSYNC_LOW 0
> `define LINE_BACK_PORCH 1
> `define LINE_DATA 2
> `define LINE_FRONT_PORCH 3
>
> `define IMAGE_VSYNC_LOW 0
> `define IMAGE_BACK_PORCH 1
> `define IMAGE_DATA 2
> `define IMAGE_FRONT_PORCH 3
>
> output VGA_Red;
> output VGA_Green;
> output VGA_Blue;
> output VGA_HSYNCH_N;
> output VGA_VSYNCH_N;
>
> reg rVGA_Red = 0;
> reg rVGA_Green = 0;
> reg rVGA_Blue = 0;
> reg rVGA_HSYNCH_N = 0;
> reg rVGA_VSYNCH_N = 0;
>
> reg latchVGA_Red = 0;
> reg latchVGA_Green = 0;
> reg latchVGA_Blue = 0;
> reg latchVGA_HSYNCH_N = 0;
> reg latchVGA_VSYNCH_N = 0;
>
> assign VGA_Red = latchVGA_Red;
> assign VGA_Green = latchVGA_Green;
> assign VGA_Blue = latchVGA_Blue;
> assign VGA_HSYNCH_N = latchVGA_HSYNCH_N;
> assign VGA_VSYNCH_N = latchVGA_VSYNCH_N;
>
> reg [2:0] lineState = 0;
> reg [2:0] imageState = 0;
> reg [10:0] pixelCounter = 0;
> reg [10:0] lineCounter = 0;
> reg devide2 = 0;
>
> always @(posedge clk) begin
> devide2 <= ~devide2;
> if (devide2) begin
> // check line
> case (lineState)
> `LINE_HSYNC_LOW: begin
> if (pixelCounter == 96) begin
> pixelCounter <= 0;
> lineState = `LINE_BACK_PORCH;
> rVGA_HSYNCH_N <= 1;
> end else pixelCounter <= pixelCounter + 1;
> end
> `LINE_BACK_PORCH: begin
> if (pixelCounter == 48) begin
> pixelCounter <= 0;
> lineState = `LINE_DATA;
> end else pixelCounter <= pixelCounter + 1;
> end
> `LINE_DATA: begin
> if (lineCounter < 480 && imageState == `IMAGE_DATA) begin
> rVGA_Red <= pixelCounter[4];
> rVGA_Green <= pixelCounter[5];
> rVGA_Blue <= pixelCounter[6];
> end else begin
> rVGA_Red <= 0;
> rVGA_Green <= 0;
> rVGA_Blue <= 0;
> end
> if (pixelCounter == 640) begin
> pixelCounter <= 0;
> lineState = `LINE_FRONT_PORCH;
> end else pixelCounter <= pixelCounter + 1;
> end
> `LINE_FRONT_PORCH: begin
> if (pixelCounter == 16) begin
> pixelCounter <= 0;
> lineState = `LINE_HSYNC_LOW;
> rVGA_HSYNCH_N <= 0;
>
> // check image
> case (imageState)
> `IMAGE_VSYNC_LOW: begin
> if (lineCounter == 2) begin
> lineCounter <= 0;
> imageState = `IMAGE_BACK_PORCH;
> rVGA_VSYNCH_N <= 1;
> end else lineCounter <= lineCounter + 1;
> end
> `IMAGE_BACK_PORCH: begin
> if (lineCounter == 29) begin
> lineCounter <= 0;
> imageState = `IMAGE_DATA;
> end else lineCounter <= lineCounter + 1;
> end
> `IMAGE_DATA: begin
> if (lineCounter == 480) begin
> lineCounter <= 0;
> imageState = `IMAGE_FRONT_PORCH;
> end else lineCounter <= lineCounter + 1;
> end
> `IMAGE_FRONT_PORCH: begin
> if (lineCounter == 16) begin
> lineCounter <= 0;
> imageState = `IMAGE_VSYNC_LOW;
> rVGA_VSYNCH_N <= 0;
> end else lineCounter <= lineCounter + 1;
> end
> default:
> imageState = `IMAGE_VSYNC_LOW;
> endcase
> end else pixelCounter <= pixelCounter + 1;
> end
> default:
> lineState = `LINE_HSYNC_LOW;
> endcase
> end
> end
>
> always @(negedge clk) begin
> latchVGA_Red <= rVGA_Red;
> latchVGA_Green <= rVGA_Green;
> latchVGA_Blue <= rVGA_Blue;
> latchVGA_HSYNCH_N <= rVGA_HSYNCH_N;
> latchVGA_VSYNCH_N <= rVGA_VSYNCH_N;
> end
>
>
> //
> // knight rider like LED scroll
> //
> reg [16:0] devide2500 = 0; // 50 MHz / 1000 = 50 kHz
> reg [16:0] devideLed = 0;
> reg [16:0] scrollLedCounter = 0;
> reg [4:0] scrollLed = 0;
>
> reg led0 = 0;
> assign led[0] = led0;
> reg [7:0] led0Power = 0;
> reg [7:0] led0Counter = 0;
>
> reg led1 = 0;
> assign led[1] = led1;
> reg [7:0] led1Power = 0;
> reg [7:0] led1Counter = 0;
>
> reg led2 = 0;
> assign led[2] = led2;
> reg [7:0] led2Power = 0;
> reg [7:0] led2Counter = 0;
>
> reg led3 = 0;
> assign led[3] = led3;
> reg [7:0] led3Power = 0;
> reg [7:0] led3Counter = 0;
>
> reg led4 = 0;
> assign led[4] = led4;
> reg [7:0] led4Power = 0;
> reg [7:0] led4Counter = 0;
>
> reg led5 = 0;
> assign led[5] = led5;
> reg [7:0] led5Power = 0;
> reg [7:0] led5Counter = 0;
>
> reg led6 = 0;
> assign led[6] = led6;
> reg [7:0] led6Power = 0;
> reg [7:0] led6Counter = 0;
>
> reg led7 = 0;
> assign led[7] = led7;
> reg [7:0] led7Power = 0;
> reg [7:0] led7Counter = 0;
>
> always @(posedge clk) begin
> if (devide2500 == 2500) begin
> devide2500 = 0;
>
> if (led0Power > led0Counter) led0 <= 1; else led0 <= 0;
> if (led0Counter == 255) led0Counter <= 0; else led0Counter <=

led0Counter + 1;
>
> if (led1Power > led1Counter) led1 <= 1; else led1 <= 0;
> if (led1Counter == 255) led1Counter <= 0; else led1Counter <=

led1Counter + 1;
>
> if (led2Power > led2Counter) led2 <= 1; else led2 <= 0;
> if (led2Counter == 255) led2Counter <= 0; else led2Counter <=

led2Counter + 1;
>
> if (led3Power > led3Counter) led3 <= 1; else led3 <= 0;
> if (led3Counter == 255) led3Counter <= 0; else led3Counter <=

led3Counter + 1;
>
> if (led4Power > led4Counter) led4 <= 1; else led4 <= 0;
> if (led4Counter == 255) led4Counter <= 0; else led4Counter <=

led4Counter + 1;
>
> if (led5Power > led5Counter) led5 <= 1; else led5 <= 0;
> if (led5Counter == 255) led5Counter <= 0; else led5Counter <=

led5Counter + 1;
>
> if (led6Power > led6Counter) led6 <= 1; else led6 <= 0;
> if (led6Counter == 255) led6Counter <= 0; else led6Counter <=

led6Counter + 1;
>
> if (led7Power > led7Counter) led7 <= 1; else led7 <= 0;
> if (led7Counter == 255) led7Counter <= 0; else led7Counter <=

led7Counter + 1;
>
> if (devideLed == 60) begin
> devideLed <= 0;
> if (led0Power > 0) led0Power <= led0Power * 255 / 256;
> if (led1Power > 0) led1Power <= led1Power * 255 / 256;
> if (led2Power > 0) led2Power <= led2Power * 255 / 256;
> if (led3Power > 0) led3Power <= led3Power * 255 / 256;
> if (led4Power > 0) led4Power <= led4Power * 255 / 256;
> if (led5Power > 0) led5Power <= led5Power * 255 / 256;
> if (led6Power > 0) led6Power <= led6Power * 255 / 256;
> if (led7Power > 0) led7Power <= led7Power * 255 / 256;
>
> if (scrollLedCounter == 60) begin
> scrollLedCounter <= 0;
> scrollLed <= scrollLed + 1;
> case (scrollLed)
> 0: led0Power <= 255;
> 1: led1Power <= 255;
> 2: led2Power <= 255;
> 3: led3Power <= 255;
> 4: led4Power <= 255;
> 5: led5Power <= 255;
> 6: led6Power <= 255;
> 7: led7Power <= 255;
> 8: led7Power <= 255;
> 9: led6Power <= 255;
> 10: led5Power <= 255;
> 11: led4Power <= 255;
> 12: led3Power <= 255;
> 13: led2Power <= 255;
> 14: led1Power <= 255;
> 15: begin led0Power <= 255; scrollLed <= 0; end
> endcase
> end else begin
> scrollLedCounter <= scrollLedCounter + 1;
> end
>
> end else begin
> devideLed <= devideLed + 1;
>
> end
>
> end else devide2500 = devide2500 + 1;
> end
>
> endmodule
>
>
> --
> Frank Buß, [email protected]
> http://www.frank-buss.de, http://www.it4-systems.de



Reply With Quote
  #4 (permalink)  
Old 07-24-2004, 11:39 AM
Frank Buss
Guest
 
Posts: n/a
Default Re: my first Verilog program

[email protected] (Swapnajit Mittra) wrote:

> 2. A *combinatorial* state machine:
>
> This is the logic that will assign the next_state
> from current states and the inputs AND NOTHING ELSE.
> Typically, a state inside the state machine will look
> like:
>
> always @* begin
> next_state = current_state;
> ...
> case (1'b1)
> current_state[STATEn_BIT]: begin
> if (...)
> next_state = STATEm;
> else
> next_state = STATEp;
> end
> ...
> endcase


this looks dangerous to me, because I don't know at which time the state
changes.

>> - how can I do "meta"-programming? For example the handling for
>> led0Power to led7Power is all the same, so I need something like a
>> loop, but how do I declare the variables as arrays and access them?

>
> If the behavior for all ledxPower are identical *all the time*
> (I did not explore your logic enough to see if they are), then
> you do not need to write 8 of them - just define one and then
> fan the output out.
>
> If they are logically identical with different inputs, then
> define one module that has the logic for one of the ledxPower
> and then instatiates it 8 times.


Do you have an example how to do it? I tried something like this:

for (i = 0; i < 8; i = i+1) begin
foo[i*8+7:i*8] <= (foo[i*8+7:i*8] >> (i*8)) + 1;
end

and expected that this is generated:

foo[0*8+7:0*8] <= (foo[0*8+7:0*8] >> (0*8)) + 1;
foo[1*8+7:1*8] <= (foo[1*8+7:1*8] >> (1*8)) + 1;
foo[2*8+7:2*8] <= (foo[2*8+7:2*8] >> (2*8)) + 1;
...

For this module:

module test(clk, led);
input clk;
output [7:0] led;
reg [7:0] rLed = 0;
assign led = rLed;
reg [7:0] i = 0;
always @(posedge clk) begin
for (i = 0; i < 4; i = i + 1) begin
rLed = rLed + i;
end
end
endmodule

it looks like it works like I expect it, because this schematic is
generated:

http://www.frank-buss.de/tmp/for.gif

> You might want to take a look at the following site for
> some example design:
>
> http://pancham.sourceforge.com


I've found another examples at www.opencores.com, but I would like to
have a reference and some tutorials. The FAQ at
http://www.faqs.org/faqs/verilog-faq/ is a bit outdated, I plan to buy
some books. Looks like this is a good one:

http://www.amazon.de/exec/obidos/ASIN/1402070896

And for comparing with VHDL perhaps this one:

http://www.amazon.de/exec/obidos/ASIN/0471899720/

Perhaps someone can comment these books or suggest other books. Some
online resources would be useful, too.

--
Frank Buß, [email protected]
http://www.frank-buss.de, http://www.it4-systems.de
Reply With Quote
  #5 (permalink)  
Old 08-07-2004, 07:56 PM
Swapnajit Mittra
Guest
 
Posts: n/a
Default Re: my first Verilog program

Frank Buss <[email protected]> wrote in message news:<[email protected]>...
> [email protected] (Swapnajit Mittra) wrote:
>
> > 2. A *combinatorial* state machine:
> >
> > This is the logic that will assign the next_state
> > from current states and the inputs AND NOTHING ELSE.
> > Typically, a state inside the state machine will look
> > like:
> >
> > always @* begin
> > next_state = current_state;
> > ...
> > case (1'b1)
> > current_state[STATEn_BIT]: begin
> > if (...)
> > next_state = STATEm;
> > else
> > next_state = STATEp;
> > end
> > ...
> > endcase

>
> this looks dangerous to me, because I don't know at which time the state
> changes.
>


No, this is not at all dangerous - your state (i.e. current_state)
only changes at the posedge of the clock, as shown in my
previous code:

always @(posedge clk) // decide over synchronous or asynch reset
if (reset)
current_state <=IDLE;
else
current_state <= next_state;

What changes in between clocks is your next_state based on how
the input changes. You do not need to know when it does, as
long as all changes take place before the next posedge of the
clock.

- Swapnajit

--
Project VeriPage: SystemVerilog, Verilog PLI, DPI and all the good stuffs.
http://www.project-veripage.com
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT +1. The time now is 11:08 AM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved