Files
ciciec2026_loongson/rtl/ip/open-la500/doc/lacc接口.md
2026-04-12 22:20:18 +08:00

6.6 KiB
Raw Blame History

LaCC 接口

LaCC(Loongarch32R Custom Coprocessor Interface) 接口是 Open-LA500 用于扩展自定义指令的接口。

指令格式

描述
opcode 固定为1100,用于确定当前指令
command 用于编码多个自定义指令将发送至lacc接口
imm 额外的立即数
rj 第一个寄存器的编码
rk 第二个寄存器的编码
rd 目的寄存器编码当目的寄存器不为0时会写回寄存器堆中

接口定义

方向为协处理器视角

通道 方向 宽度 信号名 描述
全局 input 1 lacc_flush 当处理器触发异常或分支预测失败时将该信号置位
请求 input 1 lacc_req_valid 处理器核发送请求
请求 input LACC_OP_WIDTH lacc_req_command 指令中的command域
请求 input 7 lacc_req_imm 指令中的imm域
请求 input 32 lacc_req_rj 第一个寄存器的值
请求 input 32 lacc_req_rk 第二个寄存器的值
回复 output 1 lacc_rsp_valid 指令完成信号,处理器将继续执行
回复 output 32 lacc_rsp_rdat 写回寄存器的数据
访存请求 output 1 lacc_data_valid 向dcache发送的访存请求信号
访存请求 input 1 lacc_data_ready dcache当前是否可以接受请求
访存请求 output 32 lacc_data_addr 访存地址
访存请求 output 1 lacc_data_read 是否为读请求
访存请求 output 32 lacc_data_wdata 写入数据
访存请求 output 2 lacc_data_size 访存数据大小
2'b00: byte
2'b01: half
2'b10: word
访存回复 input 1 lacc_drsp_valid dcache发送的回复信号
写请求将会在第二周期接收到该回复
读请求将会在dcache成功后接收
访存回复 input 32 lacc_drsp_data 访存得到的数据

运行流程

  1. 在解码阶段解析 lacc 指令,并将 op 和 imm 发送给执行阶段
  2. 在执行阶段lacc_req_valid为1lacc接口将接受 lacc 指令并暂停,直到lacc_rsp_valid为高才会将指令发送给下一级
  3. 如果需要访存,可以将 lacc_data_valid 置高并设置访存地址及大小等信息。当lacc_data_validlacc_data_ready同时为高则当前请求成功发送至dcache。
  4. 当指令执行完成之后将lacc_rsp_valid置高,指令将从 exe 级继续执行

lacc读请求时序,读取地址为0x1C0FFF38读取数据为0x00000000

lacc写请求时序写入地址为0x1C0FFEE8,写入数据为0x70A3A52B

自定义指令

添加自定义指令只需两步:

  1. 修改mycpu.h中的LACC_OP_SIZE为自定义指令数量(若LACC_OP_SIZE为1需要修改LACC_OP_WIDTH为1并且取消HAS_LACC的注释
  2. lacc_core.v中删除示例lacc_demo,写入自定指令代码

demo

demo实现了从两个地址载入向量点乘之后再存入缓存中的功能代码位于lacc_demo.v中。

指令

指令 op rj rk 描述
op_cfg 1 size waddr 设置写回地址及向量长度
op_lmadd 0 addr1 addr2 设置需要计算的两个内存地址对位相加再存入waddr

状态机

状态 说明 转换条件 下一状态
IDLE lacc_req_valid & op_lmadd REQ_ADDR1
REQ_ADDR1 访问addr1的数据 data_hsk(访问addr1数据) REQ_ADDR2
REQ_ADDR2 访问addr2的数据 data_hsk(访问addr2数据) FINAL
FINAL 计算结果并写回 data_hsk & req_size_nz(写入数据且size!=0) REQ_ADDR1
FINAL data_hsk & ~req_size_nz IDLE

data_hsk即lacc_data_valid & lacc_data_ready,表明当前访存请求发送成功。

数据控制

使用buffer_valid信号表示第一个地址的数据是否被接收。wdata_valid表示写回数据准备完成

buffer_valid & lacc_drsp_valid为高时说明第二个地址的数据已经返回,在该周期计算buffer_data+lacc_drsp_rdata并写入wdata

修改编译器

我们可以使用".word xxxxxxx"的格式在汇编中添加自定义指令。但是这种方式阅读不够友好,并且不利于操作数读写,例如

	asm volatile (
		"move $r5, %[addr]\n\t"
		"move $r6, %[para]\n\t"
		".word 0xc00018a0\n\t"
		::[addr]"r"(addr),[para]"r"(para)
		:"$r5", "$r6"
	);

修改编译器

我们可以修改binutils使得编译器可以识别自定义指令。

{0xc0000000, 0xf0000000, "lacc", "u22:6,r0:5,r5:5,r10:5,u15:7", 0, 0, 0, 0}
  • 根据toolchina的README编译并将bin目录添加到path中

自定义指令的格式为:

lacc command, rd, rj, rk, imm

上例可以修改为:

	asm volatile (
		"lacc 0x0, $r0, %[addr], %[para], 0x0\n\t"
		::[addr]"r"(addr), [para]"r"(para)
	);