八、RISC-V SoC外设——GPIO接口 代码讲解

2023-11-19

前几篇博文中注释了RISC-V的内核CPU部分,从这篇开始来介绍RISC-V SoC的外设部分。

另外,在最后一个章节中会上传额外添加详细注释的工程代码,完全开源,如有需要可自行下载。

目录

0 RISC-V SoC注解系列文章目录

1. 结构

2. GPIO模块

2.1 输入和输出端口

2.2 代码注解

2.3 GPIO功能实现


 

0 RISC-V SoC注解系列文章目录

零、RISC-V SoC软核笔记详解——前言

 一、RISC-V SoC内核注解——取指

 二、RISC-V SoC内核注解——译码

三、RISC-V SoC内核注解——执行

四、RISC-V SoC内核注解——除法(试商法)

五、RISC-V SoC内核注解——中断

六、RISC-V SoC内核注解——通用寄存器

七、RISC-V SoC内核注解——总线

八、RISC-V SoC外设注解——GPIO

九、RISC-V SoC外设注解——SPI接口

十、RISC-V SoC外设注解——timer定时器

十一、RISC-V SoC外设注解——UART模块(终篇)

1. 结构

如下图,我们之前介绍的RISC-V内核部分,是图中左上角的RISC-V处理器核。而内核和所有的外设都挂载在总线上,内核通过总线和外设进行数据交互。这六个外设中,RAM和ROM外设已经在之前的博文中进行了解析,因此不再赘述。现在我们来介绍外设中的GPIO外设。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQ29kZV9jb3B5MQ==,size_15,color_FFFFFF,t_70,g_se,x_16

2. GPIO模块

2.1 输入和输出端口

input wire clk,  
input wire rst,  
  
input wire we_i,  //总线写使能
input wire[31:0] addr_i,   //总线 配置IO口寄存器地址
input wire[31:0] data_i,   //总线 写数据(用来配置IO口相关寄存器)
input wire[1:0] io_pin_i,  //输入模式下,IO口的输入逻辑电平
  
output wire[31:0] reg_ctrl,  //IO口控制寄存器数据 0: 高阻,1:输出,2:输入
output wire[31:0] reg_data,  //IO口数据寄存器数据
output reg[31:0] data_o       // 总线读IO口寄存器数据

2.2 代码注解

Step1:先设计两个寄存器:gpio_ctrl(控制GPIO的输入和输出模式); gpio_data(存放GPIO的输入或输出数据)。

// 每2位控制1个IO的模式,最多支持16个IO  
// 0: 高阻,1:输出,2:输入  
reg[31:0] gpio_ctrl;  
// 输入输出数据  
reg[31:0] gpio_data;  
  
assign reg_ctrl = gpio_ctrl;  
assign reg_data = gpio_data; 

Step2:给这两个寄存器规划地址。

// GPIO控制寄存器的地址  
localparam GPIO_CTRL = 4'h0;  
// GPIO数据寄存器的地址  
localparam GPIO_DATA = 4'h4;  

Step3:通过寄存器寻址来,对上述定义的两个寄存器进行写操作,通过配置gpio_ctrl寄存器来实现GPIO的输入输出。

// 写寄存器  
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;  //通过配置寄存器gpio_ctrl来实现GPIO的输入输出
                end  
                GPIO_DATA: begin  
                    gpio_data <= data_i;  
                end  
            endcase  
        end else begin  //如果IO口是输入模式,则将输入的逻辑电平存放到gpio_data寄存器中
            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

以下代码是通过总线来读IO口相关寄存器数据。

// 读寄存器  
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  
            default: begin  
                data_o = 32'h0;  
            end  
        endcase  
    end  
end  

2.3 GPIO功能实现

在顶层tinyriscv_soc_top.v模块中,

// 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),  
    .rst(rst),  
    .we_i(s4_we_o),  
    .addr_i(s4_addr_o),  
    .data_i(s4_data_o),  
    .data_o(s4_data_i),  
    .io_pin_i(io_in),  
    .reg_ctrl(gpio_ctrl),  
    .reg_data(gpio_data)  
);  

上述代码中:

gpio[0] = (gpio_ctrl[1:0] == 2'b01)? gpio_data[0]: 1'bz; 

是说当配置寄存器gpio_ctrl[1:0]为1时,说明GPIO为输出模式,将gpio_data[0]输出至对应的IO口,如果gpio_ctrl[1:0]不为1,即为0或2,对应高阻态和输入模式,都将GPIO设置为高阻态,原因如下:

高阻态是一个数字电路里常见的术语,指的是电路的一种输出状态,既不是高电平也不是低电平,如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西而定。

 

参考:

从零开始写RISC-V处理器 | liangkangnan的博客 (gitee.io)

tinyriscv: 一个从零开始写的极简、非常易懂的RISC-V处理器核。 (gitee.com)

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

八、RISC-V SoC外设——GPIO接口 代码讲解 的相关文章

  • MOS管的知识,看这一篇就可以了

    转载 21ic电子网 2020 11 15 18 19 以下文章来源于记得诚电子设计 作者记得诚 记得诚电子设计 分享电子硬件知识 永远相信美好的事情即将发生 今天的文章简单总结一下MOS管 如下是本文目录 场效应管分类 场效应管分为结型
  • RISC-V嵌入式开发准备篇2:嵌入式开发的特点介绍

    原文出处 https mp weixin qq com s ljYZwMj3JaPN29dTAXA3bQ 随着国内第一本RISC V中文书籍 手把手教你设计CPU RISC V处理器篇 正式上市 越来越多的爱好者开始使用开源的蜂鸟E203
  • 握手2倍速率进,一倍速率出[verilog]

    module two to one parameter WORD LEN 33 input clk input arst input 2 WORD LEN 1 0 i din input i din valid output o din r
  • FPGA提示产生latch的报错

    在fpga的设计中有时会遇到 latch 的报错 1 latch是什么 Latch 就是锁存器 是一种在异步电路系统中 对输入信号电平敏感的单元 用来存储信息 锁存器在数据锁存使能时 数据被锁存 输入信号不起作用 这违背了组合逻辑中输出随输
  • 八、RISC-V SoC外设——GPIO接口 代码讲解

    前几篇博文中注释了RISC V的内核CPU部分 从这篇开始来介绍RISC V SoC的外设部分 另外 在最后一个章节中会上传额外添加详细注释的工程代码 完全开源 如有需要可自行下载 目录 0 RISC V SoC注解系列文章目录 1 结构
  • 【FPGA】面试问题及答案整理合集

    面试问题及答案整理合集 1 硬件描述语言和软件编程语言的区别 2 FPGA选型问题 3 建立时间和保持时间问题 3 亚稳态问题 4 竞争和冒险问题 5 乒乓操作问题 6 同步和异步逻辑电路 7 同步复位和异步复位 8 MOORE 与 MEE
  • Verilog HDL——Modelsim仿真

    常用testbench语法 finish 和 stop finish任务用于终止仿真并跳出仿真器 stop任务则用于中止仿真 timescale time unit time precision time unit指定计时和延时的测量单位
  • [从零开始学习FPGA编程-28]:进阶篇 - 基本组合电路-奇偶校验生成器(Verilog语言版本)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 第1章 奇偶校验生成器 1 1 什么是奇校验 1 2 Verilog语言描述
  • 时序约束理解

    异步配置信息 跨时钟域 配置信息一般set max delay按照3delay来约束 2 异步回读 rst clear信号 设置set false path 放松时序约束要求 不应分析设计中的逻辑路径 因为不关心点到点时序要求
  • 无线网络管理系统与无线路由器的区别

    第5章 波形发生器软件设计 本章我们将介绍系统的软件设计 系统中控制软件占有很重要的地位 它不仅要产生波形数据 控制波形的发生 还要控制显示电路和键盘电路 因此系统软件的好坏直接决定着系统的功能和稳定 5 1软件的总体结构 在本系统中 由于
  • 凿子3.功能模块Mux4

    我正在按照文档学习 Chisel在 Github 上 https github com ucb bar chisel3 wiki Short 20Users 20Guide 20to 20Chisel 到目前为止 一切都完美无缺 但我还是卡
  • 在 C 中实现 SB 型 riscv 指令

    我遇到了一些问题 我尝试将 32 位二进制解码为 RISCV 架构集中的 SB 类型指令 我已经移动了操作码 imm rs1 rs2 和 rd 值 但未能获得正确的 IMM 值 例如对于以下 32 位二进制 1111111000000111
  • TRICONEX MA2211-100 芯片上相互连接

    TRICONEX MA2211 100 芯片上相互连接 TRICONEX MA2211 100 所有相同的组件 io的电源 处理器 和内存将需要 但是 你可以看到所有这些带存储器和处理器的OO板 针不能嵌入到一个小的单片机上 现在是 普拉克
  • 裸机 RISC-V CPU - 处理器如何知道从哪个地址开始获取指令?

    我正在设计自己的 RISC V CPU 并且已经能够实现一些指令代码 我已经安装了 RV32I 版本的 GCC 编译器 所以我现在有了汇编器riscv32 unknown elf as可用的 我正在尝试仅用一条指令来汇编一个程序 simpl
  • RISC-V 中的旋转位

    嘿 我对 RISC V 还算陌生 我的练习题之一是 将 0x0000000000000123 的值右移 4 位 预期结果为 0x3000000000000012 即所有十六进制数字向右移动一位 而最右边的一位移动到前面 到目前为止 我了解了
  • GDB 中断命令不会在命令文件中执行

    我有一个调试脚本 它执行以下操作 设置两个断点 让我们称呼他们吧start and end断点 启动后 脚本将继续执行 直到start命中断点 once start命中断点 我执行单步执行 直到end命中断点 这是我的命令文件 end br
  • 机器模式下mret和ret指令有什么区别?

    当RISC V核心工作在机器模式时 mret和ret指令有什么区别吗 ret is a pseudoinstruction which actually is a jalr instruction while mret is a real
  • 为定制 RISC-V imafd SOC 移植 Linux

    我正在尝试构建一个 yocto演示 coreip cli我的自定义 risc v SOC 的图像仅支持imafd指示 对于 Bitbake 使用的交叉工具链的编译 我尝试更改 openembedded core 层中的 cross binu
  • RISC-V 规范引用了“hart”一词 - “hart”是什么意思?

    我找到了参考文献hart在第 35 页RISC V 2 1 规范 https content riscv org wp content uploads 2016 06 riscv spec v2 1 pdf 但是 我找不到它的定义hart在
  • 为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

    我正在读一本书 计算机组织与设计RISC V版 我遇到了 S B 和 U J 指令类型的编码 我上面提到的那些类型有奇怪的编码立即字段 S B 类型将直接字段分为两部分 这是有道理的 因为所有指令编码都必须相似 但我无法理解为什么立即字段以

随机推荐

  • maven 教程

    Maven项目管理 Maven是什么 Maven是Apache下的项目管理工具 它由纯Java语言开发 可以帮助我们更方便的管理和构建Java项目 为什么要使用Maven jar包管理 从Maven中央仓库获取标准的规范的jar包以及相关依
  • 故障:fork failed:Resource Temporarily Unavailable解决方案

    故障 fork failed Resource Temporarily Unavailable解决方案 在一次crontab bkapp txt导入N多定时任务时候 该用户无法执行任何命令 再ssh连报fork failed Resourc
  • oVirt快速安装指南

    介绍 此文档是针对第一次安装使用oVirt的用户 带领你们逐步完成oVirt的安装 基本环境设置和安装虚拟机 css 系统需求 下面介绍的系统要求只适合典型的中小规模环境的安装 若是对于安装 系统规划和负载均衡有特殊要求的用户 也可使用下面
  • 如何看待中小企业实现数字化转型难的问题?_光点科技

    中小企业在今天的商业环境中扮演着至关重要的角色 它们为就业创造了大量机会 促进了创新 支持了经济增长 然而 中小企业在数字化转型方面面临着许多挑战 这些挑战使得实现数字化转型变得困难 资源限制 中小企业通常拥有有限的资金和人力资源 这使得数
  • Onvif协议学习:12、修改分辨率

    Onvif协议学习 12 修改分辨率 文章目录 Onvif协议学习 12 修改分辨率 1 原理简介 2 函数接口 3 编码流程 4 示例代码 原文链接 https blog csdn net benkaoya article details
  • fc2 php,fc2fans_club.py

    import re from lxml import etree need install import json import ADC function def getTitle htmlcode 获取厂商 print htmlcode
  • 简单看看TypeScript、C# 和 Delphi 这三种编程语言

    TypeScript C 和 Delphi 是三种不同的编程语言 它们都有自己的特点和适用领域 在本篇博客中 我们将对这三种语言进行比较和介绍 分析它们的共同点和区别 TypeScript 是由微软公司的 Anders Hejlsberg
  • xctf-supersqli

    xctf supersqli 堆叠注入 一 堆叠注入 本次采用的靶场xctf的supersqli 一 堆叠注入 进入靶场 发现一个提示框 先随便点一下提交 发现输出了些东西 输入1 判断存在注入点 分别输如1 1 1 2 判断为单引号注入
  • MatConvNet 框架的mnist实例

    mnist 手写是被 cnn mnist m 主函数代码 function net info cnn mnist varargin 主函数 cnn mnist 功能 1 初始化CNN 2 设置各项参数 3 读取和保存数据集 4 初始化tra
  • (图像变换)Python-opencv,(批处理笛卡尔坐标系,也就是平时咱们看到的正常图片)二维彩色图像转化为极坐标系下的图像

    这个其实代码量不大 但对于我这个啥也编不出来的废柴来说我觉得真的好不容易 历经两天的痛苦折磨 终于完成了 下面进入正题 昨天我找了一天代码 然后挑挑拣拣也就找到一篇还是c 的图像极坐标化处理 代码如下 include
  • linux查看显卡型号p4卡或者t4卡_NVIDIA Tesla GPU系列P4、T4、P40以及V100参数性能对比...

    NVIDIA Tesla系列GPU适用于高性能计算 HPC 深度学习等超大规模数据计算 Tesla系列GPU能够处理解析PB级的数据 速度比使用传统CPU快几个数量级 NVIDIA Tesla GPU系列P4 T4 P40以及V100是Te
  • substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符。

    tableData sbsj result sbsj substr 0 result sbsj indexOf
  • 使用JDBC操作数据库

    导包 数据库驱动包 msql connector java 1 掌握JDBC连接数据库 1 1 JDBC 流程图 mermaid svg oRZnGw9oql7DhsSu label font family trebuchet ms ver
  • 数据结构与集合之(1)ArrayList 与 Arrays

    数据结构是指逻辑意义上的数据组织方式及其处理方式 从 直接前驱 和 直接后继 个数的维度来看 大体可以将数据结构分为以下四类 1 线性结构 0 至 1 个直接前驱 和 直接后继 线性结构包括 顺序表 链表 栈 队列等 2 树结构 0 至 1
  • 【python数据分析(22)】Matplotlib库绘图的图表样式参数(linestyle、marker、color、style)

    1 linestyle线条参数 默认是导入了相关的库 这里的代码就不再显示了 solid line style 实线样式 dashed line style 虚线样式 dash dot line style 虚点线样式 dotted lin
  • TP6框架--CRMEB学习笔记:项目初始化+环境配置

    这里给大家分享我在网上总结出来的一些知识 希望对大家有所帮助 最近在研究一个基于TP6的框架CRMEB 这里分享下我的开发心得 首先要获取原始项目文件 这里是git地址 https gitee com ZhongBangKeJi CRMEB
  • websocket协议

    WebSocket是一种在Web应用程序中实现实时双向通信的协议 一种在单个TCP连接上进行全双工通信的协议 它使得客户端和服务器之间的数据交换变得更加简单 允许服务端主动向客户端推送数据 WebSocket 与 HTTP 2 一样 其实都
  • C++-必知必会_类模板成员特化(条款48)

    类模板成员特化 再提醒一下 虽然模板的特化和类的派生之间没有任何关 系 但在特化模板的时候 不妨借鉴一下派生的精神 也就意味 着一个完全特化或局部特化通常必须重新实现 主模板具备的 所有能力 例1 主模板 template lt typen
  • Mariadb数据库之主从复制同步配置实战

    Mariadb数据库之主从复制同步配置实战 一 环境规划 二 Mariadb的主从复制介绍 1 主从复制简介 2 半同步复制介绍 3 主从复制原理图 三 安装Mariadb 1 配置yum仓库 2 检查yum仓库 3 安装mariadb 4
  • 八、RISC-V SoC外设——GPIO接口 代码讲解

    前几篇博文中注释了RISC V的内核CPU部分 从这篇开始来介绍RISC V SoC的外设部分 另外 在最后一个章节中会上传额外添加详细注释的工程代码 完全开源 如有需要可自行下载 目录 0 RISC V SoC注解系列文章目录 1 结构