I'm trying to use the module counter in Traffic_Light
I keep getting this error
Error (10159): Verilog HDL Task Definition error at TC.v(29): task "counter" is not used as a task (there are 4 of these errors for each instance of me trying to call counter)
I'm sure I'm missing something simple but I can't for the life of me figure out what.
Also I'm guessing that
if (counter_out >= 3)
done = 1;
is wrong? I think I need 011 instead of 3 but I'm not sure how to code that.
Any Verilog gurus out there that could lend a hand?
Spoilered for large
module Traffic_Light
(
Clk,
Reset,
carSensor,
HG, HY, HR, FG, FY, FR
);
input Clk;
input Reset;
input carSensor;
output HG, HY, HR, FG, FY, FR;
reg HG, HY, HR, FG, FY, FR;
wire countDone;
parameter highwayGreen = 0, highwayYellow = 1, highwayRed = 2, farmYellow = 3;
reg [3:0] state;
always @ (posedge Clk or posedge Reset)
begin
if (Reset)
state <= highwayGreen;
else
case (state)
highwayGreen:
if (carSensor == 1) begin
counter(Clk, 1, 0, countDone);
state <= highwayYellow;
end else
state <= highwayGreen;
highwayYellow:
if (countDone == 1)
state <= highwayRed;
highwayRed:
if (carSensor == 0) begin
counter(Clk, 1, 0, countDone);
state <= farmYellow;
end else
state <= highwayRed;
farmYellow:
if (countDone == 1)
state <= highwayGreen;
endcase
end
always @ (state)
begin
case (state)
highwayGreen :
begin
HG = 1;
HY = 0;
HR = 0;
FG = 0;
FY = 0;
FR = 1;
end
highwayYellow :
begin
counter(Clk, 0, 1, countDone);
HG = 0;
HY = 1;
HR = 0;
FG = 0;
FY = 0;
FR = 1;
end
highwayRed :
begin
HG = 0;
HY = 0;
HR = 1;
FG = 1;
FY = 0;
FR = 0;
end
farmYellow :
begin
counter(Clk, 0, 1, countDone);
HG = 0;
HY = 0;
HR = 1;
FG = 0;
FY = 1;
FR = 0;
end
endcase
end
endmodule
module counter (
clock ,
reset ,
enable ,
done
);
input clock ;
input reset ;
input enable ;
output done;
wire clock ;
wire reset ;
wire enable ;
reg [3:0] counter_out ;
always @ (posedge clock)
begin : COUNTER
if (reset == 1'b1) begin
counter_out <= #1 4'b0000;
done = 0;
end
else if (enable == 1'b1) begin
counter_out <= #1 counter_out + 1;
if (counter_out >= 3)
done = 1;
end
end
endmodule
Posts
It seems like you are using a counter module as a function (like you would in procedural programming), when you really shouldn't. Every instance of a module acts sort of like a thread, which operates constantly at the same time as everything else. Thus, instantiating a module in a case statement doesn't seem to make sense; rather any modules should be instantiated outside of the always blocks.
In the case statements, I would also add a default case, and else statements to the ifs to prevent unwanted memory elements.
That makes sense but how would I go about utilizing the counter in the various states without actually calling it in the state? Make a wire and set it to one when the counter is needed? This is very confusing...
When the state logic gets this complicated, I usually have the next state logic in a separate always block and keep the register instantiation very simple (state <= nextState or whatever).
Also another thing I noticed: you don't need the delay statements on a clocked module like the counter.
Is this more along the lines of what you where talking about?
This has me completely stumped.
Hint:
Is this what you want?
Hint:
Also, are you going to be synthesising this and putting it on to a CPLD/FPGA?
If so, you might want to consider making reset level triggered instead of edge triggered - a lot of the synthesis tools have trouble with registers having more than one edge trigger source.
Well once the traffic light turns yellow it needs to stay yellow for 3 clock cycles.
I thought that because each clock cycle it it rotates back into the yellow state if clockDone = 0 it would increment clock.
state: yellow->yellow->yellow->red
clock: 1 -> 2 -> 3 ->0
I guess this doesn't work? Could I just use 3 extra states instead of using the clock register?
One thing about the always block
is that it only triggers when "state" changes.
When "state" goes from yellow -> yellow, there's no change, and so no reason to increase clock.
Using three extra states is definitely an option. Perhaps not the most optimal one, but it will get the job done.
I'm not getting any errors but I did get this warning.
Warning: Circuit may not operate. Detected 11 non-operational path(s) clocked by clock "Clk" with clock skew larger than data delay. See Compilation Report for details.
It seems theres a latch in state highwayRed? Is it talking about the register yellowHighOrFarm I added?
edit :
Could you try this?
See what it says?
1.) In your always @ (state) block, add a default: case where yellowHighOrFarm, HG, HY, HR, etc, are set to 0.
2.) In your always @ (state) block, make sure yellowHighOrFarm is always assigned in every case.
3.) In your always @ (posedge... ) block, add a default: case where state <= highwayGreen.
When does it enter the default state?
If I have yellowHighOrFarm = 0; in default: it gives me this which is not what I want but it gets rid of the above warning.
comment out that line and it gives me the state transitions I want but I get
Warning: Circuit may not operate. Detected 2 non-operational path(s) clocked by clock "Clk" with clock skew larger than data delay. See Compilation Report for details.
Does this mean somewhere my logic is fucking up and It's reverting back to default resulting in a perpetual 0 on yellowHighOrFarm?
edit: I just noticed this warning
Warning (10240): Verilog HDL Always Construct warning at ELab3.v(66): inferring latch(es) for variable "yellowHighOrFarm", which holds its previous value in one or more paths through the always construct
not sure if it's relevent
One solution is to explicitly enter those states in your block, or alternatively you could try moving all assignments of yellowHighOrFarm to your always @ (posedge... block, so it ends up something like:
And other appropriate places.
Edit: Coming to think about it, yellowHighOrFarm should not be combinationally generated.
That last always @ (state) block is combinationally generating the outputs of HG, HY, HR... but yellowHighOrFarm needs to retain its state.
In which case, I recommend assigning the value of yellowHighOrFarm in your sequential (always @ (posedge...)) block.