Program Counter in Verilog. Case not working....

S

SpainHack

Guest
Hello All,

I\'m just getting started with Verilog.
I created the following Programs Counter for a simple Stack Machine.
The PC is an 8-bit register that stores the address of the command being executed.
The clock pulse at the positive edge of the clock signal (except mode = 2).
If mode = 0 reset PC to 0
If mode = 1, set the PC value to be equal to the value in the data bus.
If mode = 2, write the PC value to the data bus.
If mode = 3 do nothing (value z at data bus)
If mode = 4, increase PC by one unit.

Here is a GIST with the code...
https://gist.github.com/jemo07/5d5ba7d31bb12410888f46ca6060a1f2
I\'m testing it at: https://8bitworkshop.com

And I getting errors on:
case( pc_mode[2:0] )
Case values incompletely covered (example pattern 0x5)
3\'b000:
begin
pc_value[7:0] = 8\'b0000_0000;
(clock_divider.v:21) 20: Blocking assignments (=) in sequential (flop or latch) block
temp[7:0] = 8\'bzzzz_zzzz;

Any ideas?
I was trying to run it as an if statement but ran into this...
https://www.kevnugent.com/2020/10/22/verilog-blogpost_002/
And I decided to go with the case statement, but it does not seem to work or it\'s not properly validated in the tool...

Cheers

Jose.
 
On 12/9/2022 8:09 AM, SpainHack wrote:
Hello All,

I\'m just getting started with Verilog.
I created the following Programs Counter for a simple Stack Machine.
The PC is an 8-bit register that stores the address of the command being executed.
The clock pulse at the positive edge of the clock signal (except mode = 2).
If mode = 0 reset PC to 0
If mode = 1, set the PC value to be equal to the value in the data bus.
If mode = 2, write the PC value to the data bus.
If mode = 3 do nothing (value z at data bus)
If mode = 4, increase PC by one unit.

Here is a GIST with the code...
https://gist.github.com/jemo07/5d5ba7d31bb12410888f46ca6060a1f2
I\'m testing it at: https://8bitworkshop.com

And I getting errors on:
case( pc_mode[2:0] )
Case values incompletely covered (example pattern 0x5)

All possible case values need to be in the code. pc_mode[2:0] allows
for 8 values and your code only has 5. You can add a one default case
for the ones you don\'t need instead of adding each individually.
For instance:

default:
begin
// do something here
end

3\'b000:
begin
pc_value[7:0] = 8\'b0000_0000;
(clock_divider.v:21) 20: Blocking assignments (=) in sequential (flop or latch) block

Generally in an edge clocked \'always@\' block you should use non blocking
assignments. In other words use <= instead of just the = sign.

For instance:

pc_value[7:0] <= 8\'b0000_0000;


temp[7:0] = 8\'bzzzz_zzzz;

There may also be a problem with this.

temp[7:0] is an internal register in your module. It is my experience
that an internal register can\'t be tristated.

Any ideas?

One other thing:

I believe you should have each case statement actually do something.

I was trying to run it as an if statement but ran into this...
https://www.kevnugent.com/2020/10/22/verilog-blogpost_002/
And I decided to go with the case statement, but it does not seem to work or it\'s not properly validated in the tool...

Cheers

Jose.

I\'m a hobbyist programmer not an expert but maybe this will help.

Charlie




 
On Friday, December 9, 2022 at 9:43:43 PM UTC+1, Charlie wrote:

And I getting errors on:
case( pc_mode[2:0] )
Case values incompletely covered (example pattern 0x5)
All possible case values need to be in the code. pc_mode[2:0] allows
for 8 values and your code only has 5. You can add a one default case
for the ones you don\'t need instead of adding each individually.
For instance:

default:
begin
// do something here
end
3\'b000:
begin
pc_value[7:0] = 8\'b0000_0000;
(clock_divider.v:21) 20: Blocking assignments (=) in sequential (flop or latch) block
Generally in an edge clocked \'always@\' block you should use non blocking
assignments. In other words use <= instead of just the = sign.

For instance:
pc_value[7:0] <= 8\'b0000_0000;
temp[7:0] = 8\'bzzzz_zzzz;
There may also be a problem with this.

temp[7:0] is an internal register in your module. It is my experience
that an internal register can\'t be tristated.

I\'m a hobbyist programmer not an expert but maybe this will help.

Charlie
Thanks Charlie, I have to ponder your comments further. Yes, I have to build a test case, and like you, I’m a hobbyist, I just took some of the ideas from some of the reading I have been doing and implemented what I thought was a simple Program Counter. I have to rethink… maybe I have more reading again.
 
On Friday, December 9, 2022 at 4:43:43 PM UTC-4, Charlie wrote:
On 12/9/2022 8:09 AM, SpainHack wrote:
Hello All,

I\'m just getting started with Verilog.
I created the following Programs Counter for a simple Stack Machine.
The PC is an 8-bit register that stores the address of the command being executed.
The clock pulse at the positive edge of the clock signal (except mode = 2).
If mode = 0 reset PC to 0
If mode = 1, set the PC value to be equal to the value in the data bus.
If mode = 2, write the PC value to the data bus.
If mode = 3 do nothing (value z at data bus)
If mode = 4, increase PC by one unit.

Here is a GIST with the code...
https://gist.github.com/jemo07/5d5ba7d31bb12410888f46ca6060a1f2
I\'m testing it at: https://8bitworkshop.com

And I getting errors on:
case( pc_mode[2:0] )
Case values incompletely covered (example pattern 0x5)
All possible case values need to be in the code.

A Verilog case statement does not need to cover all possible values of the selector. For any unspecified values, the case statement simply does nothing, just like a case selector choice that has an empty list of statements. For example, even if you cover all combinations of 1 and 0, there are many other possible values.

Consider an IF statement. (forgive my syntax, I\'m not a Verilog guy)

always @(posedge clock)
begin
IF ( a == b) begin
c = d;
end
end

If A is not equal to B, this code does nothing. Because it does nothing, the FF inferred will have a clock enable.


pc_mode[2:0] allows
for 8 values and your code only has 5. You can add a one default case
for the ones you don\'t need instead of adding each individually.
For instance:

default:
begin
// do something here
end

While this is useful for debugging, it is not required. It may be useful to have a default that displays an error message.

To the OP, why not post this in comp.lang.vhdl? It\'s a quiet group, but it may spur some interest.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209
 
On 12/14/2022 6:15 AM, gnuarm.del...@gmail.com wrote:
On Friday, December 9, 2022 at 4:43:43 PM UTC-4, Charlie wrote:
On 12/9/2022 8:09 AM, SpainHack wrote:
Hello All,

I\'m just getting started with Verilog.
I created the following Programs Counter for a simple Stack Machine.
The PC is an 8-bit register that stores the address of the command being executed.
The clock pulse at the positive edge of the clock signal (except mode = 2).
If mode = 0 reset PC to 0
If mode = 1, set the PC value to be equal to the value in the data bus.
If mode = 2, write the PC value to the data bus.
If mode = 3 do nothing (value z at data bus)
If mode = 4, increase PC by one unit.

Here is a GIST with the code...
https://gist.github.com/jemo07/5d5ba7d31bb12410888f46ca6060a1f2
I\'m testing it at: https://8bitworkshop.com

And I getting errors on:
case( pc_mode[2:0] )
Case values incompletely covered (example pattern 0x5)
All possible case values need to be in the code.

A Verilog case statement does not need to cover all possible values of the selector. For any unspecified values, the case statement simply does nothing, just like a case selector choice that has an empty list of statements. For example, even if you cover all combinations of 1 and 0, there are many other possible values.

Consider an IF statement. (forgive my syntax, I\'m not a Verilog guy)

always @(posedge clock)
begin
IF ( a == b) begin
c = d;
end
end

If A is not equal to B, this code does nothing. Because it does nothing, the FF inferred will have a clock enable.

Thank you for the clarification. You are, of course, correct.
I should have stated that my answer referred to the tools he was using
(8bitworkshop). With that tool the errors he encountered were resolved
by adding all possible case values or a default case.

For what it is worth, his code synthesizes without errors using Xilinx ISE.

pc_mode[2:0] allows
for 8 values and your code only has 5. You can add a one default case
for the ones you don\'t need instead of adding each individually.
For instance:

default:
begin
// do something here
end

While this is useful for debugging, it is not required.

Okay, I didn\'t know that. I just always put a default case in there
unless all case values are used.

It may be useful to have a default that displays an error message.

Agreed.

To the OP, why not post this in comp.lang.vhdl? It\'s a quiet group, but it may spur some interest.

I agree but comp.lang.verilog would be a better choice, I think. ;-)

Charlie
 
On Wednesday, December 14, 2022 at 12:15:37 PM UTC-4, Charlie wrote:
On 12/14/2022 6:15 AM, gnuarm.del...@gmail.com wrote:
On Friday, December 9, 2022 at 4:43:43 PM UTC-4, Charlie wrote:
On 12/9/2022 8:09 AM, SpainHack wrote:
Hello All,

I\'m just getting started with Verilog.
I created the following Programs Counter for a simple Stack Machine.
The PC is an 8-bit register that stores the address of the command being executed.
The clock pulse at the positive edge of the clock signal (except mode = 2).
If mode = 0 reset PC to 0
If mode = 1, set the PC value to be equal to the value in the data bus.
If mode = 2, write the PC value to the data bus.
If mode = 3 do nothing (value z at data bus)
If mode = 4, increase PC by one unit.

Here is a GIST with the code...
https://gist.github.com/jemo07/5d5ba7d31bb12410888f46ca6060a1f2
I\'m testing it at: https://8bitworkshop.com

And I getting errors on:
case( pc_mode[2:0] )
Case values incompletely covered (example pattern 0x5)
All possible case values need to be in the code.

A Verilog case statement does not need to cover all possible values of the selector. For any unspecified values, the case statement simply does nothing, just like a case selector choice that has an empty list of statements. For example, even if you cover all combinations of 1 and 0, there are many other possible values.

Consider an IF statement. (forgive my syntax, I\'m not a Verilog guy)

always @(posedge clock)
begin
IF ( a == b) begin
c = d;
end
end

If A is not equal to B, this code does nothing. Because it does nothing, the FF inferred will have a clock enable.


Thank you for the clarification. You are, of course, correct.
I should have stated that my answer referred to the tools he was using
(8bitworkshop). With that tool the errors he encountered were resolved
by adding all possible case values or a default case.

For what it is worth, his code synthesizes without errors using Xilinx ISE.
pc_mode[2:0] allows
for 8 values and your code only has 5. You can add a one default case
for the ones you don\'t need instead of adding each individually.
For instance:

default:
begin
// do something here
end

While this is useful for debugging, it is not required.
Okay, I didn\'t know that. I just always put a default case in there
unless all case values are used.
It may be useful to have a default that displays an error message.
Agreed.

To the OP, why not post this in comp.lang.vhdl? It\'s a quiet group, but it may spur some interest.

I agree but comp.lang.verilog would be a better choice, I think. ;-)

Huh, I could have sworn I caught that and changed it. lol

--

Rick C.

+ Get 1,000 miles of free Supercharging
+ Tesla referral code - https://ts.la/richard11209
 

Welcome to EDABoard.com

Sponsor

Back
Top