外观
DSMC 读写示例
2026-02-06
本文将介绍如何通过 DSMC 总线进行通讯,通过 DSMC 的 localbus master 与 PGL22GB 实现的 localbus server 进行通讯,并验证写入数据。
DSMC 简介
DSMC(Double Data Rate Serial Memory Controller)是瑞芯微 SoC 内部的一种高速存储与本地总线控制器,用于通过 DDR 方式与外部 PSRAM 或 LocalBus 设备(如 FPGA)进行数据通信,具有高频高速的特性。
DSMC 特性
- 支持双倍数据速率(DDR)接口
- 支持最多选择 4 个芯片
- 支持 8 线和 16 线串行传输模式
- 支持可配置的写/读连续地址合并事务
- 支持可配置的写/读边界地址拆分事务
- 支持将 WRAP 传输转换为 INCR 传输
- 支持字节访问
- 支持可配置的 DQS 输入时钟延迟线
使用 DSMC 向 FPGA 写入数据
本示例使用 DSMC localbus master 向 FPGA 写入数据,FPGA 将数据存储入大小为 16KB 的 RAM 当中,DSMC localbus master 再将写入数据读出来,进行值的判断。
硬件连接
RC-PI-3506 开发板与 FPGA 扩展板需要连接。

创建工程点击展开
依次点击 “文件” -> “新建” -> "RT-Thread RuiChing App 项目"。

在弹出新建向导中选择 开发版 、BSP: 、示例 、 调试器/下载器。选择好之后点击 “完成”。

点击 “完成” 后,等待工程创建完成。

创建完成。

构建工程点击展开
单击工程使工程进入 Active-Debug 模式。

点击工具栏上的构建按钮进行工程编译。

构建成功后,会显示构建成功的信息。

固件下载点击展开
固化设备树

固化 APP

核心示例代码
adc_sample.c
static int test_dsmc_read_write(void)
{
int i;
int err_count = 0;
rt_uint64_t t_start, t_end;
rt_uint64_t write_cycles, read_cycles;
const int WORD_NUM = 4 * 1024; // 4K word = 16KB
uintptr_t BASE_ADDR = 0xC0000000;
rt_uint32_t *write_buf = rt_malloc(WORD_NUM * 4);
rt_uint32_t *read_buf = rt_malloc(WORD_NUM * 4);
if (!write_buf || !read_buf)
{
rt_kprintf("malloc failed!\n");
return -1;
}
for (i = 0; i < WORD_NUM; i++)
{
write_buf[i] = 0x12345678 + i;
}
t_start = rt_hw_global_timer_get();
for (i = 0; i < WORD_NUM; i++)
{
writel(write_buf[i], BASE_ADDR + i * 4); //RK3506读写的时候,只能4字节对齐访问
}
t_end = rt_hw_global_timer_get();
write_cycles = t_end - t_start;
t_start = rt_hw_global_timer_get();
for (i = 0; i < WORD_NUM; i++)
{
read_buf[i] = readl(BASE_ADDR + i * 4);
}
t_end = rt_hw_global_timer_get();
read_cycles = t_end - t_start;
for (i = 0; i < WORD_NUM; i++)
{
if (read_buf[i] != write_buf[i])
{
err_count++;
rt_kprintf("ERR[%d]: R=0x%08X W=0x%08X\n",
i, read_buf[i], write_buf[i]);
if (err_count > 10)
{
rt_kprintf("......\n");
break;
}
}
}
float write_time_us = (float)write_cycles / 24.0f;
float read_time_us = (float)read_cycles / 24.0f;
float total_bytes = WORD_NUM * 4.0f;
float write_speed = (total_bytes / (1024 * 1024)) / (write_time_us / 1e6);
float read_speed = (total_bytes / (1024 * 1024)) / (read_time_us / 1e6);
if (err_count == 0)
{
rt_kprintf("\n==== DSMC TEST PASS ====\n");
rt_kprintf("Write: %lu cycles, %.2f us, %.2f MB/s\n",
write_cycles, write_time_us, write_speed);
rt_kprintf("Read : %lu cycles, %.2f us, %.2f MB/s\n",
read_cycles, read_time_us, read_speed);
}
else
{
rt_kprintf("\n==== DSMC TEST FAIL ====\n");
rt_kprintf("Error count: %d\n", err_count);
}
rt_free(write_buf);
rt_free(read_buf);
return 0;
}
MSH_CMD_EXPORT(test_dsmc_read_write, test dsmc read write);运行程序
RC-PI-3506 输出:
msh />test_dsmc_read_write
==== DSMC TEST PASS ====
Write: 73640 cycles, 3068.33 us, 5.09 MB/s
Read : 240044 cycles, 10001.83 us, 1.56 MB/s
msh />test_dsmc_read_write工程实现说明
- 当前 DSMC 为 8 位宽模式,开启 DSMC 的 CS0 的 FIFO region。
- 默认频率为 12MHZ ,在示例工程的 board 下的 board.dts 可以修改,引脚复用也可以在该文件中修改。
- 除 DSMC 的引脚复用与时钟,其他的配置暂时不支持修改。
- DSMC 的 DMA 以及 中断 暂时不支持开启。
FPGA 工程的迁移
可以使用如下方法,将 FPGA 工程迁移到不同版本的 IDE 上: 在目标 IDE 上创建 PGL22GB-6MBG324 工程,添加被移植工程的 dsmc.fdc, dsmc_port.v, led.v 文件。 RAM 和 PLL IP 核心按如下方式进行配置即可:


