Forum Discussion
Creating a bidirectional bus
I want to connect a USB chip (FT245R) to a CPLD. To do that I need a bidirectional 8-bit bus. I thought I could declare the pins to be bidirectional and with a mux, read to or write from the pins as necessary. My Verilog code for the mux is:
[code]
always @(negedge clk) begin: TESTUSB_MUX
if ((TXE == 0)) begin
USBBUS <= OUTBUS;
end
else if ((RXF == 0)) begin
INBUS <= USBBUS;
end
end
[\code]
But the Fitter generates errors, e.g., Error: Can't reserve pin "USBBUS[0]" because its name already exists with a different direction
How can a bidirectional bus be created?
13 Replies
- Altera_Forum
Honored Contributor
I rewrote my code as:
output [7:0] USBBUS; wire [7:0] USBBUS; reg [7:0] outbus; wire [7:0] inbus; always @(negedge clk) begin if ((TXE == 0)) begin USBBUS <= outbus; end else if ((RXF == 0)) begin inbus <= USBBUS; end else begin USBBUS <= 8'hz; end end Now my error is: error (10137): verilog hdl procedural assignment error at testusb.v(344): object "usbbus" on left-hand side of assignment must have a variable data type Any suggestions? - Altera_Forum
Honored Contributor
You cannot use a "wire" in an "always" statement. It's a Verilog idiosyncranie.
What people usually do, when dealing with bi-directional signals is to decompose it in 3 variants (input, output and output enable) like this.input wire USBBUS; wire USBBUS_i; reg USBBUS_o; reg USBBUS_oe; assign USBBUS_i = USBBUS; assign USBBUS = USBBUS_oe == 1'b1 ? USBBUS_o : 8'hzz; always @ (negedge clk) begin if(write condition) begin USBBUS_o <= outbus; USBBUS_oe <= 1'b1; end else begin USBBUS_o <= 8'hxx; USBBUS_oe <= 1'b0; end if (read condition) begin inbus <= USBBUS_i; end end - Altera_Forum
Honored Contributor
Thanks for your reply. I made the changes you suggested but now Quartus generates this error message: error (10219): verilog hdl continuous assignment error at testusb.v(353): object "inbus" on left-hand side of assignment must have a net type
Line 353 is the assignment to inbus in: if (read condition) begin inbus <= USBBUS_i; end I made the following changes indicated by <<<<
but that didn't solve the probleminput wire USBBUS; wire USBBUS_i; reg USBBUS_o; reg USBBUS_oe; assign USBBUS_i = USBBUS; assign USBBUS = USBBUS_oe == 1'b1 ? USBBUS_o : 8'hzz; wire inbus_i; //<<<< assign inbus_i = inbus; //<<<< always @(negedge clk) begin if(TXE == 0) begin USBBUS_o <= outbus; USBBUS_oe <= 1'b1; end else begin USBBUS_o <= 8'hxx; USBBUS_oe <= 1'b0; end if (RXF == 0) begin inbus_i <= USBBUS_i; //<<<< end end - Altera_Forum
Honored Contributor
To mention a simple thing, a bidirectional port has to be declared as inout.
- Altera_Forum
Honored Contributor
Yes, the USBBUS pins are bidirectional. The signal inbus_i is not connected to any pins. Thanks for your reply.
- Altera_Forum
Honored Contributor
My code was not meant to be complete; I had assumed you have a
declaration.reg inbus - Altera_Forum
Honored Contributor
inbus was declared as a wire, it is the input to another module.
With the changes below indicated by "<<<<" full compilation was successful. I haven't test it...wire USBBUS_i; reg USBBUS_o; reg USBBUS_oe; assign USBBUS_i = USBBUS; assign USBBUS = USBBUS_oe == 1'b1 ? USBBUS_o : 8'hzz; wire inbus_w; reg inbus_r; assign inbus_w = inbus; // <<<< assign inbus = inbus_r; // <<<< always @(negedge clk) begin if(TXE == 0) begin USBBUS_o <= outbus; USBBUS_oe <= 1'b1; end else begin USBBUS_o <= 8'hxx; USBBUS_oe <= 1'b0; end if (RXF == 0) begin inbus_r <= inbus; // <<<< end end - Altera_Forum
Honored Contributor
Please take note that my code was just "pseudo-code" to illustrate the concept.
I have no idea if the TXE and RFX logic is right or wrong for your application. Don't test it; simulate it first. - Altera_Forum
Honored Contributor
I understand and that's very good advice. I have tested with MyHDL and ModelSim the module that deals with TXE and outbus and the module that deals with RXF and inbus. TXE and RXF are mutually exclusive in that only one can be true at any time. The code I am working on now, which requires the bidirectional bus, is additional test code to be downloaded into my device to determine if these modules will actually communicate with the USB device (FT245R). I'll write some code to test the bidirectional buffer stuff with ModelSim.
Thanks very much for your help. Thanks also to FvM for the comment regarding the inout declaration. - Altera_Forum
Honored Contributor
I wrote some test code to check out the above code in ModelSim (starter edition 6.6d) but got several errors I didn't understand. So I thought I would try something simpler. I found the bidirec code on Altera. I have attached the file containing my test code to this post.
In ModelSim the code compiles OK. But when I click Start Simulation I get the following errors: "Illegal output or inout port connection for "port 'outp'". "Illegal output or inout port connection for "port 'bidir'". If all assignments to outp and bidir in module simBidir are commented the same errors are generated. If in module simBidir outp type is changed to a wire and the assignment to outp in STIMULUS is removed the illegal port connection error for outp is not generated when the simulation is started. But this cannot be done for bidir; at least, I assume an assignment to bidir should be permitted. What have I got wrong now?