TinyRISC-V
处理器系统的顶层模块(tinyriscv_soc_top
)。它负责将不同的外设(如 UART、GPIO、SPI、Timer、JTAG 等)与处理器(tinyriscv
)连接,并管理这些外设和处理器之间的数据交互。该模块的功能可以按以下几个部分进行解释。
模块的输入输出端口
-
输入端口:
clk
:时钟信号,用于同步各个模块。rst
:复位信号,用于初始化系统。uart_debug_pin
:用于调试的 UART 输入引脚。uart_rx_pin
:UART 接收数据引脚。jtag_TCK
、jtag_TMS
、jtag_TDI
:JTAG 接口的输入信号。spi_miso
:SPI MISO(主输入从输出)信号。
-
输出端口:
over
:指示是否完成某项测试。succ
:指示是否成功完成某项测试。halted_ind
:指示 JTAG 是否请求处理器暂停(halt)。uart_tx_pin
:UART 发送数据引脚。gpio
:GPIO 引脚,用于和外部设备进行交互。spi_mosi
、spi_ss
、spi_clk
:SPI 信号。
模块内的信号定义与外设接口
在该模块中,信号被分为 主接口(Master Interface) 和 从接口(Slave Interface),用于与外设之间的数据传输。
Master 接口:
每个接口都是与外设连接的,提供地址、数据、读写控制等信号。
例如:
m0_addr_i
,m0_data_i
,m0_data_o
,m0_req_i
,m0_we_i
是第一个主接口的信号,它们用于控制访问内存或外设的操作。
Slave 接口:
这些是从外设获得的信号,表示从外设接收到的数据,或者发送到外设的数据。
例如:
s0_addr_o
,s0_data_o
,s0_data_i
,s0_we_o
是与第一个外设(如 ROM)相关的信号。
主要外设实例化与连接
-
TinyRISC-V 处理器模块(
tinyriscv
):tinyriscv
是处理器核心,它的输入输出包括时钟、复位、地址、数据等信号。- 处理器核心连接到总线接口,处理外设请求。
tinyriscv u_tinyriscv( .clk(clk), .rst(rst), .rib_ex_addr_o(m0_addr_i), .rib_ex_data_i(m0_data_o), .rib_ex_data_o(m0_data_i), .rib_ex_req_o(m0_req_i), .rib_ex_we_o(m0_we_i), .int_i(int_flag) );
-
ROM(只读存储器):
u_rom
是一个 ROM 模块,提供指令存储功能。- ROM 的地址和数据通过主从接口进行交换。
rom u_rom( .clk(clk), .rst(rst), .we_i(s0_we_o), .addr_i(s0_addr_o), .data_i(s0_data_o), .data_o(s0_data_i) );
-
RAM(随机访问存储器):
u_ram
是一个 RAM 模块,提供数据存储功能。
ram u_ram( .clk(clk), .rst(rst), .we_i(s1_we_o), .addr_i(s1_addr_o), .data_i(s1_data_o), .data_o(s1_data_i) );
-
Timer(定时器):
u_timer
是定时器模块,提供定时功能并生成中断信号。- 中断信号(
timer0_int
)会传递到中断控制模块。
timer timer_0( .clk(clk), .rst(rst), .data_i(s2_data_o), .addr_i(s2_addr_o), .we_i(s2_we_o), .data_o(s2_data_i), .int_sig_o(timer0_int) );
-
GPIO(通用输入输出):
gpio_0
是 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) );
assign gpio[0] = (gpio_ctrl[1:0] == 2'b01)? gpio_data[0]: 1'bz;
assign io_in[0] = gpio[0];
-
gpio_ctrl 控制寄存器:通过 gpio_ctrl[1:0] 和 gpio_ctrl[3:2],控制每个 GPIO 引脚的工作模式(输入/输出)。
-
当 gpio_ctrl[n:n-1] == 2’b01 时,gpio[n] 引脚会输出 gpio_data[n] 中的值。
-
否则,GPIO 引脚处于 三态模式(1’bz),表示引脚不输出值。三态(1’bz):三态表示 无驱动状态,即 GPIO 引脚没有被模块驱动,允许其他外部电路控制该引脚。
-
io_in 寄存器:gpio 引脚的输入数据传递给 io_in,表示外部输入信号被读取到 io_in 寄存器中。
-
SPI(串行外设接口):
spi_0
是 SPI 模块,用于与其他设备进行串行数据通信。
spi spi_0( .clk(clk), .rst(rst), .data_i(s5_data_o), .addr_i(s5_addr_o), .we_i(s5_we_o), .data_o(s5_data_i), .spi_mosi(spi_mosi), .spi_miso(spi_miso), .spi_ss(spi_ss), .spi_clk(spi_clk) );
-
JTAG(联合测试行动组):
u_jtag_top
是 JTAG 调试模块,通常用于调试和设备的测试。
jtag_top u_jtag_top( .clk(clk), .jtag_rst_n(rst), .jtag_pin_TCK(jtag_TCK), .jtag_pin_TMS(jtag_TMS), .jtag_pin_TDI(jtag_TDI), .jtag_pin_TDO(jtag_TDO), .reg_we_o(jtag_reg_we_o), .reg_addr_o(jtag_reg_addr_o), .reg_wdata_o(jtag_reg_data_o), .reg_rdata_i(jtag_reg_data_i) );
如何通过地址映射连接外设
外设(如 gpio
, uart
, timer
等)会通过 address decoding
机制与总线连接,确保每个外设有不同的地址空间。通过 addr_i
信号,外设能够判断是否该响应来自 CPU 或其他外设的数据访问。
总结:
- 该模块是一个
TinyRISC-V
处理器的系统顶层(SoC)设计,连接了多个外设。 - 通过 主接口(Master Interface) 和 从接口(Slave Interface),外设和 CPU 进行数据交换。
- 外设包括 ROM、RAM、Timer、GPIO、SPI、JTAG 等,所有外设通过总线进行地址解码。
- 每个外设(如
timer
,gpio
,uart
等)都通过addr_i
和data_o
/data_i
信号来进行地址和数据的交换。
具体源码见https://gitee.com/liangkangnan/tinyriscv/blob/master/rtl/soc/tinyriscv_soc_top.v