Skip to content

Commit

Permalink
[gpio] Add input capability to gpio.
Browse files Browse the repository at this point in the history
Retrieve input values from switches and buttons and send them
over UART.

Signed-off-by: Abdullah Varici <[email protected]>
  • Loading branch information
Abdullah Varici committed Dec 15, 2022
1 parent 323638a commit d8c8adb
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 24 deletions.
16 changes: 8 additions & 8 deletions data/pins_artya7.xdc
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { IO_CLK
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { IO_CLK }];

## Switches
#set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L12N_T1_MRCC_16 Sch=sw[0]
#set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L13P_T2_MRCC_16 Sch=sw[1]
#set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L13N_T2_MRCC_16 Sch=sw[2]
#set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L14P_T2_SRCC_16 Sch=sw[3]
set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports { SW[0] }]; #IO_L12N_T1_MRCC_16 Sch=sw[0]
set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports { SW[1] }]; #IO_L13P_T2_MRCC_16 Sch=sw[1]
set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports { SW[2] }]; #IO_L13N_T2_MRCC_16 Sch=sw[2]
set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports { SW[3] }]; #IO_L14P_T2_SRCC_16 Sch=sw[3]

## RGB LEDs
set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { RGB_LED[0] }]; #IO_L18N_T2_35 Sch=led0_b
Expand All @@ -35,10 +35,10 @@ set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { LED[2]
set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L24N_T3_A00_D16_14 Sch=led[7]

## Buttons
#set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { btn[0] }]; #IO_L6N_T0_VREF_16 Sch=btn[0]
#set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { btn[1] }]; #IO_L11P_T1_SRCC_16 Sch=btn[1]
#set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { btn[2] }]; #IO_L11N_T1_SRCC_16 Sch=btn[2]
#set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { btn[3] }]; #IO_L12P_T1_MRCC_16 Sch=btn[3]
set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports { BTN[0] }]; #IO_L6N_T0_VREF_16 Sch=btn[0]
set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports { BTN[1] }]; #IO_L11P_T1_SRCC_16 Sch=btn[1]
set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports { BTN[2] }]; #IO_L11N_T1_SRCC_16 Sch=btn[2]
set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports { BTN[3] }]; #IO_L12P_T1_MRCC_16 Sch=btn[3]

## Pmod Header JA
#set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_0_15 Sch=ja[1]
Expand Down
16 changes: 10 additions & 6 deletions rtl/fpga/top_artya7.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,30 @@
// This is the top level SystemVerilog file that connects the IO on the board to the Ibex Demo System.
module top_artya7 (
// These inputs are defined in data/pins_artya7.xdc
input IO_CLK,
input IO_RST_N,
output [ 3:0] LED,
output [11:0] RGB_LED,
output UART_TX
input IO_CLK,
input IO_RST_N,
input [3:0] SW,
input [3:0] BTN,
output [3:0] LED,
output [11:0] RGB_LED,
output UART_TX
);
parameter SRAMInitFile = "";

logic clk_sys, rst_sys_n;

// Instantiating the Ibex Demo System.
ibex_demo_system #(
.GpiWidth(8),
.GpoWidth(4),
.PwmWidth(12),
.SRAMInitFile(SRAMInitFile)
) u_ibex_demo_system (
//input
.clk_sys_i(clk_sys),
.rst_sys_ni(rst_sys_n),

.gp_i({SW, BTN}),

//output
.gp_o(LED),
.pwm_o(RGB_LED),
Expand Down
25 changes: 15 additions & 10 deletions rtl/system/gpio.sv
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

module gpio #(
GpiWidth = 8,
GpoWidth = 16
) (
input logic clk_i,
Expand All @@ -16,36 +17,40 @@ module gpio #(
output logic device_rvalid_o,
output logic [31:0] device_rdata_o,

input logic [GpiWidth-1:0] gp_i,
output logic [GpoWidth-1:0] gp_o
);
logic [GpoWidth-1:0] gp_d;
logic gp_en;
logic [GpoWidth-1:0] gp_o_d;
logic gp_o_wr_en;
logic gp_i_rd_en, gp_i_rd_en_reg;

always @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
gp_o <= '0;
device_rvalid_o <= '0;
gp_i_rd_en_reg <= '0;
end else begin
if (gp_en) begin
gp_o <= gp_d;
if (gp_o_wr_en) begin
gp_o <= gp_o_d;
end

device_rvalid_o <= device_req_i;
gp_i_rd_en_reg <= gp_i_rd_en;
end
end

assign gp_en = device_req_i & device_we_i & (device_addr_i[9:0] == 0);
assign gp_o_wr_en = device_req_i & device_we_i & (device_addr_i[9:0] == 0);
assign gp_i_rd_en = device_req_i & ~device_we_i & (device_addr_i[9:0] == 4);

for (genvar i_byte = 0; i_byte < 4; ++i_byte) begin : g_gp_d;
if (i_byte * 8 < GpoWidth) begin : g_gp_d_inner
for (genvar i_byte = 0; i_byte < 4; ++i_byte) begin : g_gp_o_d;
if (i_byte * 8 < GpoWidth) begin : g_gp_o_d_inner
localparam int gpo_byte_end = (i_byte + 1) * 8 <= GpoWidth ? (i_byte + 1) * 8 : GpoWidth;
assign gp_d[gpo_byte_end - 1 : i_byte * 8] =
assign gp_o_d[gpo_byte_end - 1 : i_byte * 8] =
device_be_i[i_byte] ? device_wdata_i[gpo_byte_end - 1 : i_byte * 8] :
gp_o[gpo_byte_end - 1 : i_byte * 8];
end
end

assign device_rdata_o = {{(32 - GpoWidth){1'b0}}, gp_o};
assign device_rdata_o = gp_i_rd_en_reg ? {{(32 - GpiWidth){1'b0}}, gp_i} : {{(32 - GpoWidth){1'b0}}, gp_o};

logic unused_device_addr, unused_device_be, unused_device_wdata;

Expand Down
4 changes: 4 additions & 0 deletions rtl/system/ibex_demo_system.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
// - Timer.
// - Debug module.
module ibex_demo_system #(
parameter int GpiWidth = 8,
parameter int GpoWidth = 16,
parameter int PwmWidth = 12,
parameter SRAMInitFile = ""
) (
input logic clk_sys_i,
input logic rst_sys_ni,

input logic [GpiWidth-1:0] gp_i,
output logic [GpoWidth-1:0] gp_o,
output logic [PwmWidth-1:0] pwm_o,
output logic uart_tx_o
Expand Down Expand Up @@ -275,6 +277,7 @@ module ibex_demo_system #(
);

gpio #(
.GpiWidth ( GpiWidth ),
.GpoWidth ( GpoWidth )
) u_gpio (
.clk_i (clk_sys_i),
Expand All @@ -288,6 +291,7 @@ module ibex_demo_system #(
.device_rvalid_o(device_rvalid[Gpio]),
.device_rdata_o (device_rdata[Gpio]),

.gp_i,
.gp_o
);

Expand Down
4 changes: 4 additions & 0 deletions sw/common/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ uint32_t get_outputs(gpio_t gpio) {
return DEV_READ(gpio);
}

uint32_t get_inputs(gpio_t gpio) {
return DEV_READ(gpio);
}

void set_output_bit(gpio_t gpio, uint32_t output_bit_index,
uint32_t output_bit) {
output_bit &= 1;
Expand Down
2 changes: 2 additions & 0 deletions sw/common/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
#include <stdint.h>

#define GPIO_OUT_REG 0x0
#define GPIO_IN_REG 0x4

typedef void* gpio_t;

#define GPIO_FROM_BASE_ADDR(addr)((gpio_t)addr)

void set_outputs(gpio_t gpio, uint32_t outputs);
uint32_t get_outputs(gpio_t gpio);
uint32_t get_inputs(gpio_t gpio);

void set_output_bit(gpio_t gpio, uint32_t output_bit_index,
uint32_t output_bit);
Expand Down
4 changes: 4 additions & 0 deletions sw/demo/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ int main(void) {
puts("Hello World! ");
puthex(last_elapsed_time);
putchar('\n');
puts("Input Value: ");
puthex(get_inputs(GPIO0 + GPIO_IN_REG));
putchar('\n');
set_output_bit(GPIO0, cur_output_bit_index, cur_output_bit);

// Cycling through green LEDs
set_output_bit(GPIO0, cur_output_bit_index, cur_output_bit);
Expand Down

0 comments on commit d8c8adb

Please sign in to comment.