diff --git a/rtl/perips/gpio.v b/rtl/perips/gpio.v index dbf9b74..4c8c5da 100644 --- a/rtl/perips/gpio.v +++ b/rtl/perips/gpio.v @@ -15,7 +15,7 @@ */ - +// GPIO模块 module gpio( input wire clk, @@ -28,38 +28,65 @@ module gpio( output reg[31:0] data_o, output reg ack_o, - output wire io_pin + + input wire[1:0] io_pin_i, + output wire[31:0] reg_ctrl, + output wire[31:0] reg_data ); + // GPIO控制寄存器 + localparam GPIO_CTRL = 4'h0; + // GPIO数据寄存器 localparam GPIO_DATA = 4'h4; + // 每2位控制1个IO的模式,最多支持16个IO + // 0: 高阻,1:输出,2:输入 + reg[31:0] gpio_ctrl; + // 输入输出数据 reg[31:0] gpio_data; - assign io_pin = gpio_data[0]; + assign reg_ctrl = gpio_ctrl; + assign reg_data = gpio_data; + // 写寄存器 always @ (posedge clk) begin if (rst == 1'b0) begin gpio_data <= 32'h0; + gpio_ctrl <= 32'h0; end else begin if (we_i == 1'b1) begin case (addr_i[3:0]) + GPIO_CTRL: begin + gpio_ctrl <= data_i; + end GPIO_DATA: begin gpio_data <= data_i; end endcase + end else begin + if (gpio_ctrl[1:0] == 2'b10) begin + gpio_data[0] <= io_pin_i[0]; + end + if (gpio_ctrl[3:2] == 2'b10) begin + gpio_data[1] <= io_pin_i[1]; + end end end end + // 读寄存器 always @ (*) begin if (rst == 1'b0) begin data_o = 32'h0; end else begin case (addr_i[3:0]) + GPIO_CTRL: begin + data_o = gpio_ctrl; + end GPIO_DATA: begin data_o = gpio_data; end diff --git a/rtl/soc/tinyriscv_soc_top.v b/rtl/soc/tinyriscv_soc_top.v index d458987..4637409 100644 --- a/rtl/soc/tinyriscv_soc_top.v +++ b/rtl/soc/tinyriscv_soc_top.v @@ -28,7 +28,7 @@ module tinyriscv_soc_top( output wire halted_ind, // jtag是否已经halt住CPU信号 output wire tx_pin, // UART发送引脚 - output wire io_pin, // GPIO引脚 + inout wire[1:0] gpio, // GPIO引脚 input wire jtag_TCK, // JTAG TCK引脚 input wire jtag_TMS, // JTAG TMS引脚 @@ -134,6 +134,10 @@ module tinyriscv_soc_top( // timer0 wire timer0_int; + // gpio + wire[1:0] io_in; + wire[31:0] gpio_ctrl; + wire[31:0] gpio_data; assign int_flag = {7'h0, timer0_int}; @@ -227,6 +231,13 @@ module tinyriscv_soc_top( .tx_pin(tx_pin) ); + // io0 + assign gpio[0] = (gpio_ctrl[1:0] == 2'b01)? gpio_data[0]: 1'bz; + assign io_in[0] = gpio[0]; + // io1 + assign gpio[1] = (gpio_ctrl[3:2] == 2'b01)? gpio_data[1]: 1'bz; + assign io_in[1] = gpio[1]; + // gpio模块例化 gpio gpio_0( .clk(clk), @@ -237,7 +248,9 @@ module tinyriscv_soc_top( .data_i(s4_data_o), .data_o(s4_data_i), .ack_o(s4_ack_i), - .io_pin(io_pin) + .io_pin_i(io_in), + .reg_ctrl(gpio_ctrl), + .reg_data(gpio_data) ); // spi模块例化