03-26-2012 01:20 AM
Hello there,
I want to interface a chip with FPGA and it has 8 data pins(bidirectional). Some time to give command to the chip I need to write to these data lines and some times I need to read from these data lines, Hence I am defining these 8 data lines as "inout reg [7:0] Data" in my verilog code. This gives me an error as " unexpected token: 'reg' ". Even after it is given in the language template as " inout reg [7:0] <name>". I need to define it as 'reg' as I am assigning some values to "Data" in my code, and if I don't define it as 'reg' it gives error as "Reference to vector wire 'Data' is not a legal reg or variable lvalue" and "Illegal left hand side of blocking assignment" on the lines where I assign values to Data(e.g.: " Data = 8'h09 ").
Help me out with your innovative ideas.
Thanks.
03-27-2012 04:51 AM - edited 03-27-2012 01:27 PM
module read(
input clk,
input INTR,
input WAIT,
output reg [1:0] MODE,
output reg A0,// 0-> index reg., 1-> data buffer
output reg CS0,CS1,RD, WR,
inout [7:0] Data // NOT a reg.
);
reg [7:0] Dout = 0;
reg [5:0] state = set_CTRLB;
reg [7:0] din = 0;
initial begin
A0 = 0;
RD = 1; // "to write
WR = 0; // to the chip"
Dout = 8'b0;
row = 0;
col = 0;
count = 0;
state = set_CTRLB;
end
assign Data = RD ? Dout : 8'bz; // data bus driver is tri-state (disabled) when READing, RD is asserted LOW
always@ (posedge clk)
case (state)
set_CTRLB : begin
CS0 <= 0; // "to select
CS1 <= 1; // the chip"
MODE <= 2'b00; // Microprocessor Bus Mode
A0 <= 0;
RD <= 1;
WR <= 0;
Dout <= 8'h09; // here I am Writing to data pins //
state <= write_CTRLB;
end
write_CTRLB : begin
A0 <= 1;
Dout <= 8'b00001101;// " //
state <= wait_30us;
end
wait_30us :
if (count == 360) state <= set1_CTRLA;
else count <= count + 1;
set1_CTRLA : begin
A0 <= 0;
Dout <= 8'h08;// " //
state <= read_CTRLA;
end
read_CTRLA : begin
RD <= 0;
WR <= 1;
if(count == 6) begin
din <= Data; // Here I am Reading from data pins Learn to use non-blocking assignments!
state <= row_read;
count <= 0;
end
else count <= count + 1;
end
row_read :
if (col == 256) state <= img_read;
else begin
col <= col + 1;
state <= set1_CTRLA;
end
img_read :
if(row == 300) state <= last_case;
else begin
row <= row + 1;
state <= set1_CTRLA;
end
last_case : begin
end
endcase
endmodule
-- Bob Elkind
03-26-2012 01:46 AM
Hi,
FPGAs can not have bidirectional lines inside the design.
So you need to split your Bus in to two busses DataIn and DataOut.
With IOBUF elements these are then merged in the IOB.
Be aware that you need to controll the direction of the dataflow (e.g. with some WriteEnable signal) with the help of the Tristate controll line of the IOBUFs.
Havea nice synthesis
Eilert
03-26-2012 04:35 AM
If FPGA's can't allow bidirectional bus then why it is given there in template under synthesis construct / port / registered / bidirectional (inout), with the syntax " inout reg [7:0] <name> ".
And still you are right then how can I assign single pin to two different signals(inBUF and outBUF) in ucf file?
03-26-2012 05:00 AM - edited 03-27-2012 12:32 AM
If FPGA's can't allow bidirectional bus then why it is given there in template under synthesis construct / port / registered / bidirectional (inout), with the syntax " inout reg [7:0] <name> ".
Those are for package pins connected to external components on the circuit board. There is no provision for multi-driver tri-state busses internal to the FPGA.
And still you are right then how can I assign single pin to two different signals(inBUF and outBUF) in ucf file?
This should be an error. Only the signal name for the package pin (see diagram below) should be in the .UCF file for assigning pin locations.
3-state buffer (OBUFT)
+---------------+ bonding
output signal >----->| in out |>-------+ pad
output enable >----->| out ena | | +-----+
+---------------+ | | |
+---<>| |<>----<> <inout> package pin
+---------------+ | | |
input signal <------| out in |<-------+ +-----+
+---------------+
input buffer (IBUF)
If you use the <inout> signal as an input to your logic, then the synthesiser will automatically insert an input buffer between the package pin and the FPGA's internal logic. This is a general rule. Se the IOB description for the target device family for details and exceptions (IODELAY blocks, for example).
-- Bob Elkind
03-26-2012 11:42 PM
Thanks for your valuable reply sir, but still I am confused about the declaration of my signal("Data") in code. What should I declare it. Because still I do not get the answer of my 1st question.
1) if I define like "inout reg [7:0] Data" in my verilog code, it gives me an error as " unexpected token: 'reg' ".
2) if I define it as "inout [7:0] Data" it gives error as "Reference to vector wire 'Data' is not a legal reg or variable lvalue" and "Illegal left hand side of blocking assignment" on the lines where I assign values to Data(e.g.: " Data = 8'h09 ").
How can I solve this?
If I define it as input then I can't assign commands to it and if I define it as output then also it won't work.
"output reg" can work, but I am not sure that at the time of reading through this pins (i.e. at the time of input) whether it will give me the input value of it will just read last stored data in that "output reg".
To make the case understandable I am elaborating the thing. I am interfacing a fingerprint chip with FPGA. To initialize the chip I need to give some sequence of command to the chip through this 8 data bits and after initialization I need to read the fingerprint pixels one by one through the same 8 data pins.
So finally, I should define these data lines as __________?
03-27-2012 12:33 AM - edited 03-27-2012 12:36 AM
This seems like a Verilog syntax error in your source code.
Please post your top-level source code, where IO ports are defined, to better understand your description.
-- Bob Elkind
03-27-2012 01:25 AM
module read(
input clk,
input INTR,
input WAIT,
output reg [1:0] MODE,
output reg A0,// 0-> index reg., 1-> data buffer
output reg CS0,CS1,RD, WR,
inout reg [7:0] Data
);
parameter set_CTRLB = 6'b000000;
parameter write_CTRLB = 6'b000001;
parameter wait_30us = 6'b000010;
parameter set1_CTRLA = 6'b000110;
parameter read_CTRLA = 6'b000111;
parameter row_read = 6'b001000;
parameter img_read = 6'b001001;
parameter last_case = 6'b001010;
integer row;
integer col;
integer count;
reg [5:0] state;
reg [7:0] din;
initial begin
A0 = 0;
RD = 1; // "to write
WR = 0; // to the chip"
Data = 8'b0;
row = 0;
col = 0;
count = 0;
state = set_CTRLB;
end
always@ (posedge clk) begin
case (state)
set_CTRLB : begin
CS0 = 0; // "to select
CS1 = 1; // the chip"
MODE = 2'b00; // Microprocessor Bus Mode
A0 = 0;
RD = 1;
WR = 0;
Data = 8'h09; // here I am Writing to data pins //
state = write_CTRLB;
end
write_CTRLB : begin
A0 = 1;
Data = 8'b00001101;// " //
state = wait_30us;
end
wait_30us : begin
if (count == 360) begin
state = set1_CTRLA;
end
else begin
count = count + 1;
end
end
set1_CTRLA : begin
A0 = 0;
Data = 8'h08;// " //
state = read_CTRLA;
end
read_CTRLA : begin
RD = 0;
WR = 1;
if(count == 6) begin
din = Data;// Here I am Reading from data pins //
state = row_read;
count = 0;
end
else begin
count = count + 1;
end
end
row_read : begin
if (col == 256) begin
state = img_read;
end
else begin
col = col + 1;
state = set1_CTRLA;
end
end
img_read : begin
if(row == 300) begin
state = last_case;
end
else begin
row = row + 1;
state = set1_CTRLA;
end
end
last_case : begin
end
endcase
end
endmodule
03-27-2012 02:12 AM
Hi,
just a guess:
Is ist possible that it can not be declared this way, because there is no FF between OBUF and pad?
Possible solution approach:
Do it with out the reg in your declaration.
Then declare the internal signals for DataIn and DataOut as regs.
Use some conditional assignment for Data to become 'Z' during reads.
e.g. (metasyntax)
if (~read)
Data <= DataOut;
else
Data <= "ZZZZZZZZZZ"; // use correct vector size
end;
In any way, you need to declare the unidirectional busses inside your module.
You can always read from Data to DataIn with a non blocking assignment, and then work with DataIn as if it were Data for reading the bus, even during active writes.
Have a nice synthesis
Eilert
03-27-2012 02:36 AM
This also don't work as it shows me error as " 'Data' is not a legal reg or variable lvalue" at the line Data <= Data_out;
when I define Data as inout only (without 'reg' ).
03-27-2012 04:23 AM - edited 03-27-2012 04:24 AM
Is there an output enable for the (inout) port DATA? If not, this is an output, not a bidirectional (inout) port
-- Bob Elkind
03-27-2012 04:51 AM - edited 03-27-2012 01:27 PM
module read(
input clk,
input INTR,
input WAIT,
output reg [1:0] MODE,
output reg A0,// 0-> index reg., 1-> data buffer
output reg CS0,CS1,RD, WR,
inout [7:0] Data // NOT a reg.
);
reg [7:0] Dout = 0;
reg [5:0] state = set_CTRLB;
reg [7:0] din = 0;
initial begin
A0 = 0;
RD = 1; // "to write
WR = 0; // to the chip"
Dout = 8'b0;
row = 0;
col = 0;
count = 0;
state = set_CTRLB;
end
assign Data = RD ? Dout : 8'bz; // data bus driver is tri-state (disabled) when READing, RD is asserted LOW
always@ (posedge clk)
case (state)
set_CTRLB : begin
CS0 <= 0; // "to select
CS1 <= 1; // the chip"
MODE <= 2'b00; // Microprocessor Bus Mode
A0 <= 0;
RD <= 1;
WR <= 0;
Dout <= 8'h09; // here I am Writing to data pins //
state <= write_CTRLB;
end
write_CTRLB : begin
A0 <= 1;
Dout <= 8'b00001101;// " //
state <= wait_30us;
end
wait_30us :
if (count == 360) state <= set1_CTRLA;
else count <= count + 1;
set1_CTRLA : begin
A0 <= 0;
Dout <= 8'h08;// " //
state <= read_CTRLA;
end
read_CTRLA : begin
RD <= 0;
WR <= 1;
if(count == 6) begin
din <= Data; // Here I am Reading from data pins Learn to use non-blocking assignments!
state <= row_read;
count <= 0;
end
else count <= count + 1;
end
row_read :
if (col == 256) state <= img_read;
else begin
col <= col + 1;
state <= set1_CTRLA;
end
img_read :
if(row == 300) state <= last_case;
else begin
row <= row + 1;
state <= set1_CTRLA;
end
last_case : begin
end
endcase
endmodule
-- Bob Elkind
03-27-2012 04:58 AM
03-27-2012 05:04 AM
Hereby I have attached pin description of the chip. They have mentioned that this data pins are bidirectional (D[7:0] (Pins 11-14, 17-20) at bottom of the very first page), and they have not mentioned anything like "output enable".
If you want to read the data pins from the sensor, you cannot drive different data onto the data pins from the FPGA at the same time.
It's like a telephone conversation. You cannot hear your girlfriend or your wife on the phone unless you stop talking yourself. The output enable on the FPGA is like the TALK vs. LISTEN button.
-- Bob Elkind
03-27-2012 05:17 AM
I got the thing about the enable signal that are "read bar" and "write bar" signals and I am setting them accordingly (you can see it in my code), but the problem is that I can not assign any value to data when it is declared as inout, it gives error as " 'Data' is not a legal reg or variable lvalue"
03-27-2012 05:20 AM - edited 03-27-2012 01:29 PM
Please read my last 3 responses, and pay attention to the highlighted changes to your code.
If you do not understand something, please ask questions.
Online user forums are not efficient for teaching logic design. It is better learning this in a classroom with a chalkboard, from an instructor, face to face.
-- Bob Elkind
03-27-2012 05:33 AM
I got it sir, thanks for your support and coolness during the conversation, sorry if I've asked too much questions without understanding. I didn't intend to do so.
Thanks once again.
03-27-2012 05:41 AM
sorry if I've asked too much questions without understanding. I didn't intend to do so.
No apologies are needed. I am more concerned that you do not ask enough questions.
Do the responses make sense? Learning bidirectional busses for the first time is not easy. Learning Verilog at the same time is also not easy. It helps that you are patient and taking time to understand what has been written.
-- Bob Elkind