Reputation: 35
I'm trying to implement a morse code display on my FPGA. I've written a lot of code but I keep getting the same error message. Before I get into that though, please take a look at the assignment. To be clear, I'm not asking for someone to do the assignment for me. I just need help debugging my code.
"Part IV In this part of the exercise you are to implement a Morse-code encoder using an FSM. The Morse code uses patterns of short and long pulses to represent a message. Each letter is represented as a sequence of dots (a short pulse), and dashes (a long pulse). For example, the first eight letters of the alphabet have the following representation:
A • —
B — • • •
C — • — •
D — • •
E •
F • • — •
G — — •
H • • • •
Design and implement a Morse-code encoder circuit using an FSM. Your circuit should take as input one of the first eight letters of the alphabet and display the Morse code for it on a red LED. Use switches SW2−0 and pushbuttons KEY1−0 as inputs. When a user presses KEY1, the circuit should display the Morse code for a letter specified by SW2−0 (000 for A, 001 for B, etc.), using 0.5-second pulses to represent dots, and 1.5-second pulses to represent dashes. Pushbutton KEY0 should function as an asynchronous reset.
Here is the code I have written:
module part4 (SELECT, button, CLOCK_50, RESET, led);
input [2:0]SELECT;
input RESET, button, CLOCK_50;
output reg led=0;
reg [26:0] COUNT=0; //register that keeps track of count
reg [1:0] COUNT2=0; //keeps track of half seconds
reg halfsecflag=0; //goes high every time half second passes
reg dashflag=0; // goes high every time 1 and half second passes
reg [3:0] code; //1 is dot and 0 is dash. There are 4 total
reg [1:0] c3=2'b00; //keeps track of the index we are on in the code.
reg [2:0] STATE; //register to keep track of states in the state machine
wire done=0; //a flag that goes up when one morse pulse is done.
reg ending=0; //another flag that goes up when a whole morse letter has
flashed
reg [1:0] length; //This is the length of the morse letter. It varies from 1
to 4
wire i; // if i is 1, then the state machine goes to "dot". if 0 "dash"
assign i = code[c3];
assign done= (halfsecflag)&&(~ending)&&~led;
parameter START= 3'b000, DOT= 3'b001, DASH= 3'b010, DELAY= 3'b011, IDLE=
3'b100;
parameter A= 3'b000, B=3'b001, C=3'b010, D=3'b011, E=3'b100, F=3'b101,
G=3'b110, H=3'b111;
always @(posedge CLOCK_50 or posedge RESET) //making counter
begin
if (RESET == 1)
COUNT <= 0;
else if (COUNT==25'd25000000)
begin
COUNT <= 0;
halfsecflag <= 1;
end
else
begin
COUNT <= COUNT+1;
halfsecflag <=0;
end
end
always @(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1)
begin
COUNT2 <= 2'd00;
dashflag<=1'b0;
end
else if ((COUNT2==2)&&(halfsecflag))
begin
COUNT2 <= 2'd0;
dashflag<=1'b1;
end
else if ((halfsecflag)&&(COUNT2!=2))
begin
COUNT2<= COUNT2+2'd1;
dashflag<=1'b0;
end
end
always @(posedge button or RESET) //asynchronous reset
begin
STATE<=IDLE;
end
always@(*) begin //State machine
case (STATE)
START: begin
led <= 1;
if (i) STATE <= DOT;
else STATE <= DASH;
end
DOT: begin
if (halfsecflag && ~ending) STATE <= DELAY;
else if (ending) STATE<= IDLE;
else STATE<=DOT;
end
DASH: begin
if ((dashflag)&& (~ending))
STATE <= DELAY;
else if (ending)
STATE <= IDLE;
else STATE <= DASH;
end
DELAY: begin
led <= 0;
if ((halfsecflag)&&(ending))
STATE<=IDLE;
else if ((halfsecflag)&&(~ending))
STATE<=START;
else STATE <= DELAY;
end
IDLE: begin
c3<=2'b00;
if (button) STATE<=START;
STATE<=IDLE;
end
default: STATE <= IDLE;
endcase
end
always @(posedge button)
begin
case (SELECT)
A: length<=2'b01;
B: length<=2'b11;
C: length<=2'b11;
D: length<=2'b10;
E: length<=2'b00;
F: length<=2'b11;
G: length<=2'b10;
H: length<=2'b11;
default: length<=2'bxx;
endcase
end
always @(posedge button)
begin
case (SELECT)
A: code<= 4'b0001;
B: code<= 4'b1110;
C: code<= 4'b1010;
D: code<= 4'b0110;
E: code<= 4'b0001;
F: code<= 4'b1011;
G: code<= 4'b0100;
H: code<= 4'b1111;
default: code<=4'bxxxx;
endcase
end
always @(*)
begin
if (c3==length)
begin
c3=2'b00; ending<=1;
end
else if (done)
c3= c3+2'b01;
end
endmodule
The error code I keep getting is Error (10028): Can't resolve multiple constant drivers for net "c3[1]" at part4.v(68)
Also in green above this error code, it says inferred latch a few different times. This doesn't seem good! Can you take a look at my code and see if you can figure out why I'm getting this error message?
Update: This is not a duplicate of my previous question. Before I was asking for tips on how to create a delay using verilog. In this question I was asking for help debugging my code. The error message I got was not making sense to me. I looked at the other answers on stack exchange regarding that error code but none of them made sense to me.
Upvotes: 0
Views: 1032
Reputation: 10261
You're missing a couple of (very) basic principles - you can't code hardware without them. Note that I'm using VHDL terminology here ('signal'/'process'/etc), but the idea is exactly the same in Verilog, if a little harder to find the right words.
if(c3==length)
must read c3, case STATE
must read state).You fix (1) by recoding so that all signals are driven from only one 'owner' process.
Fixing (2) is more difficult. In a combinatorial process (alway @*
) make sure you either give all outputs default values first, or make sure that you never read anything before you've written it, so that there's no confusion about whether memory is inferred. Your combinatorial process to derive STATE is wrong. You read STATE, and then write it. You should have 2 signals: current state, and next state. You should read the current state, and create the next one.
You've got other problems, but you need to fix those 2 first.
Upvotes: 1