I have written a single-pin GPIO module for my project, and it is working fine. A simplified version looks like this:
module gpio_port( input clk, input reset, ... inout gpio_pin ); reg read_data; reg write_data; reg pin_direction; // 1: Write, 0: Read // This line is problematic. assign gpio_pin = pin_direction == 1'b1 ? write_data : 1'bZ; always @(posedge clk or negedge reset) begin // ... read_data <= gpio_pin; write_data <= ... end
I now want to extend this concept to a full 16-bit GPIO-port. So when I tried extending it, I came across a problem: In the version with only a single pin, the direction bit is used to determine whether the write bit should be put onto the inout wire, or if it should be driven high-Z. But I can't figure out, in the 16-bit wide example, how to selectively set the single bits in the inout pin vector to high-Z or the the bit in the write register.
module gpio_port( input clk, input reset, ... inout [15:0] gpio_pin ); reg [15:0] read_data; reg [15:0] write_data; reg [15:0] pin_direction; // 1: Write, 0: Read // This line is problematic. assign gpio_pin = ???
My problem is that I am pretty new to Verilog, so I don't even know what to google for here, so I am sorry if this question is super trivial. I understand that I could just use a single direction flag, but I would like the pins to be individually definable as either input or output.
What I have tried:
I am currently using the following solution, which is super hacky:
assign gpio_pins = (pin_direction == 1'b1) ? write_data : 1'bZ; assign gpio_pins = (pin_direction == 1'b1) ? write_data : 1'bZ; assign gpio_pins = (pin_direction == 1'b1) ? write_data : 1'bZ; // ... and on and on ..