Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
21616 Discussions

multiple driver error during simulation

Altera_Forum
Honored Contributor II
2,617 Views

Hi 

I am doing a project and am stuck in the synthesis part in Quartus. 

The code was successfully compiled using icarus verilog software.But while compiling the code in Quartus , I get some error messages. 

The code is as follows with its description: 

 

/* 

Whenever positive edge of switch occurs , I need to take the incoming 8 bits (serial inputs on a single pin) and after that I  

have to discard all the bits, until the next posedge of switch. These bits are coming from a parallel in serial out register.  

These bits are stored in a reg called c and i is an integer which keeps the count.  

 

*/ 

module test(si,po,clk,switch,flag); 

input si,clk,switch; 

 

output reg [7:0] po; 

reg [7:0] c,d; 

output reg flag; 

reg count; 

//reg flag; 

integer j,i; 

initial i=0; 

initial flag=0; 

initial count=0; 

always@(posedge clk) 

begin 

if (flag==1) 

begin 

 

c[i]=si; 

i=i+1; 

if(i==8) 

begin 

//count<=1; 

//po<=c; 

po<=(c[7:4]*10)+c[3:0]; 

i=0; 

flag<=0; 

end 

end 

 

end 

 

always@(posedge switch) 

begin 

flag<=1;  

end 

endmodule 

 

The error messges are as follows: 

 

Error: Can't elaborate top-level user hierarchy 

Error (10029): Constant driver at test.v(16) 

Error (10028): Can't resolve multiple constant drivers for net "flag" at test.v(38) 

 

Could anyone help in rectifying the mistake?
0 Kudos
17 Replies
Altera_Forum
Honored Contributor II
1,792 Views

Your flag is driven in two processes. the second process sets it permanently to high... 

You must have a clock input as fast as serial stream (at least) then you run a counter(integer 0 ~ 8) set at zero at MSB or LSB location then increment to 8 and reset zero. 

(vhdl clocked process) --detect edge of switch switch_d <= switch; if switch = '1' and switch_d = '0' then count <= 1; elsif count < 8 then count <= count + 1; end if; if count < 8 then output(count) <= input; end if; if count = 7 then valid <= '1'; else valid <= '0'; end if;
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

Hi Kaz 

I have some doubts on your expalaination as follows: 

switch_d <= switch; if switch /= switch_d then count <= 1; else count <= count + 1; end if; 

1)by this are you detecting positive edge of switch 

2) 

output <= input(count); 

what does this do?
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

I just corrected the output assignment. 

Yes I detect switch rising level, the count is set to 1 due to one clock latency. 

for safer design you may put this for edge detection: 

if switch = '1' and switch_d = '0' then instead
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

 

--- Quote Start ---  

 

(vhdl clocked process) --detect edge of switch switch_d <= switch; if switch = '1' and switch_d = '0' then count <= 1; elsif count < 8 then count <= count + 1; end if; if count < 8 then output(count) <= input; end if; if count = 7 then valid <= '1'; else valid <= '0'; end if;  

--- Quote End ---  

 

As per the specifications the first 8 inputs are to be taken at the positive edge of switch. 

So why do you set count =1 at +ve edge and increase it by 1 when there's no posedge of switch? 

2)  

if count < 8 then output(count) <= input; end if; 

what is this used for?
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

You are right, I am still playing with this code for demo only as I am not aware of your inputs behaviour. 

remember you can only detect switch edge one clock period after it rises. 

I am not sure if switch will rise once only or many times.  

 

you can run count 0~7 instead of 0 ~ 8 then it will set back to 0 ready waiting for switch to go up again. 

 

if switch = '1' and switch_d = '0' then 

count <= 1; 

else 

count <= count + 1; -- 0~7 free running 

end if; 

 

output(count) <= input; 

 

...etc.
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

 

--- Quote Start ---  

 

I am not sure if switch will rise once only or many times.  

 

 

...etc. 

--- Quote End ---  

 

Yes switch is allowed transitions  

"if switch = '1' and switch_d = '0' then" If I am not wrong this is detecting the positive edge 

So my count needs to be increased only when there is a positive edge and inputs(serial 8 bits) need to be stored in a reg. 

 

Moreover, me being familiar with Verilog, not VHDL, the syntax  

output(count) <= input; 

is troubling me
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

if your 8 bits are serial then they can't all come at rising edge of switch but one after the other as per input clock edge otherwise you need to clearify this point. I know RS232 uses no clock. Instead you run a counter to read bits by guess in effect... is that your case as well? is your clock as fast as serial bit stream?

0 Kudos
Altera_Forum
Honored Contributor II
1,791 Views

Do you mean one bit arrives per switch edge?

0 Kudos
Altera_Forum
Honored Contributor II
1,791 Views

Well what I intend to do is that the serial bits are coming at every clock edge(global clock) . i use the switch mechanism to detect that my inputs are stable and I am ready to take the incoming 8 bits serially. So the value of count needs to be increased only when I am taking the inputs. 

Hope this would clarify my specifications.
0 Kudos
Altera_Forum
Honored Contributor II
1,791 Views

 

--- Quote Start ---  

Do you mean one bit arrives per switch edge? 

--- Quote End ---  

 

 

its per clock edge
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

The counter is used to move the current input bit to the coorect bit index of output. Thats why I say output(count) <= input i.e.: 

output(0) <= input bit when count = 0 

output(1) <= input bit when count = 1 ...etc. 

 

so count must go up at speed of incoming serial bits.
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

Ok well trying out some suggestions, I am here with the final code 

 

 

module test1(si,po,clk,switch,flag); 

input si,clk,switch; 

 

output reg [7:0] po; 

reg [7:0] c,d; 

output reg flag; 

reg check; 

reg count; 

//reg flag; 

integer j,i; 

initial i=0; 

initial flag=0; 

initial count=0; 

always@(posedge clk) 

begin 

if(switch==0) 

check=1; 

if(switch==1 & check==1)  

begin 

check<=0; 

flag<=1; 

end 

 

if (flag==1) 

 

begin 

 

c[i]=si; 

i=i+1; 

///end 

if(i==8) 

begin 

 

po<=(c[7:4]*10)+c[3:0]; 

i=0; 

flag<=0; 

 

end 

end 

 

end 

 

endmodule 

 

Can someone suggest how to optimise this code . I am using a CPLD board which says it requires 94 macrocells for this code but it has got only 64.:)
0 Kudos
Altera_Forum
Honored Contributor II
1,791 Views

aside from resource issue, I think you need a bit more thought on the issue of counting. you need to count 0 ~7 and then freeze on zero until next switch edge.  

One way is this: 

if switch = '1' ... 

count <= 1; 

elsif flag = '1' then 

count <= count + 1; 

end if; 

 

flag <= '1' when count > 0 else '0';
0 Kudos
Altera_Forum
Honored Contributor II
1,791 Views

The multiplier/ adder is going to take too much resource.

0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

To avoid the multiplier you can use shift and addition for 10 i.e. multiply by 8 using 3 bit shift then multiply by 2 using one bit shift then add products

0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

Thank You Kaz for the help. 

I am still short of 13 macrocells and also I would like to extend this code for 16 bits instead of 8 bits. 

Any concrete solution?
0 Kudos
Altera_Forum
Honored Contributor II
1,792 Views

I haven't done verilog for ages. I believe your integer (i ) may imply 32 bits in hardware. You only need 3 bits so try constraining that e.g. by using reg.

0 Kudos
Reply