本文介绍的是rocket-chip dcache flush和dachehe discard功能。

功能的说明可以参考文档《SiFive E76 Core Complex Manual 21G1.01.00》

CFLUSH.D.L1

  • Implemented as state machine in L1 data cache, for cores with data caches.
  • Only available in M-mode.
  • When rs1 = x0, CFLUSH.D.L1 writes back and invalidates all lines in the L1 data cache.
  • When rs1 != x0, CFLUSH.D.L1 writes back and invalidates the L1 data cache line containing the virtual address in integer register rs1.
  • If the effective privilege mode does not have write permissions to the address in rs1, then a store access or store page-fault exception is raised.
  • If the address in rs1 is in an uncacheable region with write permissions, the instruction has no effect but raises no exceptions.
  • Note that if the PMP scheme write-protects only part of a cache line, then using a value for rs1 in the write-protected region will cause an exception, whereas using a value for rs1 in the write-permitted region will write back the entire cache line.

CDISCARD.D.L1

  • Implemented as state machine in L1 data cache, for cores with data caches.
  • Only available in M-mode.
  • Opcode 0xFC200073: with optional rs1 field in bits [19:15].
  • When rs1 = x0, CDISCARD.D.L1 invalidates, but does not write back, all lines in the L1 data cache. Dirty data within the cache is lost.
  • When rs1 ≠ x0, CDISCARD.D.L1 invalidates, but does not write back, the L1 data cache line containing the virtual address in integer register rs1. Dirty data within the cache line is lost.
  • If the effective privilege mode does not have write permissions to the address in rs1, then a store access or store page-fault exception is raised.
  • If the address in rs1 is in an uncacheable region with write permissions, the instruction has no effect but raises no exceptions.
  • Note that if the PMP scheme write-protects only part of a cache line, then using a value for rs1 in the write-protected region will cause an exception, whereas using a value for rs1 in the write-permitted region will invalidate and discard the entire cache line.

L1Dcache.h头文件的内容。

#include <stdint.h>#define STR1(x) #x
#ifndef STR
#define STR(x) STR1(x)
#endif#define CFLUSH_D_L1_REG(rs1)  \0xFC000073      |          \(rs1 << (7+5+3)) |          \

#define CFLUSH_D_L1_ALL()   \0xFC000073      |      \

#define FLUSH_D_ALL()   \
{           \asm volatile (".word " STR(CFLUSH_D_L1_ALL()) "\n\t" ::: "memory"); \
}           \

//Stanard macro that passes rs1 via registers
#define FLUSH_D_REG(rs1) CFLUSH_D_L1_INST(rs1,13)//rs1 is data
//rs_1 si the register number to use
#define CFLUSH_D_L1_INST(rs1, rs1_n) \
{                    \register uint32_t rs1_ asm("x" # rs1_n) = (uint32_t) rs1; \asm volatile (".word " STR(CFLUSH_D_L1_REG(rs1_n)) "\n\t" :: [_rs1] "r" (rs1_) : "memory"); \
}                                    \

#define CDISCARD_D_L1_REG(rs1)  \0xFC200073      |          \(rs1 << (7+5+3)) |          \

#define CDISCARD_D_L1_ALL() \0xFC200073      |      \

#define DISCARD_D_ALL() \
{           \asm volatile (".word " STR(CDISCARD_D_L1_ALL()) "\n\t" ::: "memory"); \
}           \

//Stanard macro that passes rs1 via registers
#define DISCARD_D_REG(rs1) CDISCARD_D_L1_INST(rs1,13)//rs1 is data
//rs_1 si the register number to use
#define CDISCARD_D_L1_INST(rs1, rs1_n) \
{                    \register uint32_t rs1_ asm("x" # rs1_n) = (uint32_t) rs1; \asm volatile (".word " STR(CDISCARD_D_L1_REG(rs1_n)) "\n\t" :: [_rs1] "r" (rs1_) : "memory"); \
}

测试代码。

#include "encoding.h"
#include "L1Dcache.h"#define U32 *(volatile unsigned int *)
#define DEBUG_SIG   0x70000000
#define DEBUG_VAL   0x70000004
#define DATA_SIZE   10int input1_data[DATA_SIZE] =
{41, 833, 564, 187, 749, 350, 132, 949, 584, 805, 621,   6, 931, 890, 392, 694, 961, 110, 116, 296,426, 314, 659, 774, 319, 678, 875, 376, 474, 938, 539, 569, 203, 280, 759, 606, 511, 657, 195,  81,267, 229, 337, 944, 902, 241, 913, 826, 933, 985, 195, 960, 566, 350, 649, 657, 181, 111, 859,  65,288, 349, 141, 905, 886, 264, 576, 979, 761, 241, 478, 499, 403, 222, 444, 721, 676, 317, 224, 937,288, 119, 615, 606, 389, 351, 455, 278, 367, 358, 584,  62, 985, 403, 346, 517, 559, 908, 775, 255
};int input2_data[DATA_SIZE] =
{454, 335,   1, 989, 365, 572,  64, 153, 216, 140, 210, 572, 339, 593, 898, 228,  12, 883, 750, 646,500, 436, 701, 812, 981, 150, 696, 564, 272, 258, 647, 509,  88, 703, 669, 375, 551, 936, 592, 569,952, 800, 584, 643, 368, 489, 328, 313, 592, 388, 543, 649, 979, 997, 814,  79, 208, 998, 629, 847,704, 997, 253, 715, 430, 415, 538, 700,   4, 494, 100, 864, 693, 416, 296, 285, 620,  78, 351, 540,646, 169, 527, 289, 796, 801, 720, 758, 745,  92, 989, 271, 853, 788, 531, 222, 461, 241, 358, 332};//--------------------------------------------------------------------------
// handle_trap functionvoid handle_trap()
{asm volatile ("nop");while(1);
}//--------------------------------------------------------------------------
// dcache flush & discard functionvoid dcache( int n, int a[], int b[])
{int i;for ( i = 0; i < n; i++ )U32(0x80001000+4*i) = a[i] + b[i];//flush all dcacheFLUSH_D_ALL();for ( i = 0; i < n; i++ )U32(0x80001000+4*i) = i + 10086;//discard all dcacheDISCARD_D_ALL();for ( i = 0; i < n; i++ )U32(0x60001000+4*i) = U32(0x80001000+4*i);
}//--------------------------------------------------------------------------
// Mainvoid main()
{dcache(DATA_SIZE, input1_data, input2_data);U32(DEBUG_SIG) = 0xFF;
}

代码步骤说明:

  1. 第一次读入memory 0x80001000+4*i的值,并重新赋值为a[i] + b[i]。
  2. 运行FLUSH_D_ALL()函数,flush all dcache,将dcache中数据全部刷回memory。
  3. 第二次读入memory 0x80001000+4*i的值,并重新赋值为i+10086。
  4. 运行DISCARD_D_ALL()函数,丢弃dcache中的全部数据。
  5. 将memory 0x80001000+4i的值输出到0x60001000+4i中,可以看到memory 0x80001000+4*i的值会从memory中重新读取(第三次读取),而非从dcache中获取。

细化的仿真图,就不详细贴出了,只贴一个总的运行过程图。

图中说明如下,波形图的最上面有白色的时间点标志。

  • 红色箭头:从memory中获取执行指令,指令存放的起始地址为0x8000_0000。
  • 蓝色箭头:第一次读取memory 0x80001000+4*i的值。
  • 黄色箭头:运行FLUSH_D_ALL()函数,将dcache中的数据全部写回到memory中。
  • 黄色箭头和白色箭头之间:这里有第二次读取memory 0x80001000+4*i的值,但我忘了标出来。
  • 白色箭头:运行DISCARD_D_ALL()函数,丢弃dcache中的全部数据。
  • 绿色箭头:第三次从memory中读取0x80001000+4i的值,并输出至0x60001000+4i中。

memory值的说明。

  • 第一次读取memory 0x80001000+4*i的值:memory初始值。
  • flush后,memory 0x80001000+4*i的值:a[i] + b[i]。
  • 第二次读取memory 0x80001000+4*i的值:a[i] + b[i]。
  • discard后,memory 0x80001000+4*i的值:a[i] + b[i]。
  • 第三次读取memory 0x80001000+4*i的值:a[i] + b[i]。
  • 写到0x60001000+4*i中的值:a[i] + b[i]。

这里只说明了flush all dcache 和 discard all dcache,单条dcache line的flush和discard大家可以根据L1Dcache.h的内容自行尝试。

Rocket-chip-Dcache Flush Discard相关推荐

  1. Rocket Chip 介绍

    Rocket  Chip 是基于 Chisel 开发的一款开源的 SoC 生成器,具有可综合的RTL.通过配置可以生成两种基于 RISC-V 指令集的通用处理器就.Rocket-Chip 中有两种处理 ...

  2. chisel(Rocket Chip)中如何参数化芯片系统

    2021.9.5 有些地方添加了一点自己的理解!!! 0 绪论 前面已经介绍了chisel的初级和高级参数化. 如何把这些东西有效的在系统中组织起来呢?如何在系统中快捷的使用他们?这篇文章主要解决这个 ...

  3. 【ESWIN编程大赛】五、2020年11月12日陈工直播笔记

    文章目录 一.pint api功能说明 1.1.背景 1.2.需求 1.3.功能模块以及说明 1.3.1.组成模块层次 1.3.2.Memory Management 1.3.3.1D/2D/3D 内 ...

  4. RISC-V BOOM核学习

    来源:RISC-V BOOM documentation RISC-V BOOM核学习 The Berkeley Out-of-Oder Machine INTRODUCTION RV64GC Fig ...

  5. 芯片开发语言:Verilog 在左,Chisel 在右

    来源 | 老石谈芯 在最近召开的RISC-V中国峰会上,中科院计算所的包云岗研究员团队正式发布了名为"香山"的开源高性能处RISC-V处理器.前不久我有幸和包老师就这个事情做了一次 ...

  6. 片上总线协议学习(1)——SiFive的TileLink与ARM系列总线的概述与对比

    link 片上总线协议学习(1)--SiFive的TileLink与ARM系列总线的概述与对比 finally 27 人赞同了该文章 一.背景介绍 随着超大规模集成电路的迅速发展,半导体工业进入深亚微 ...

  7. 在“芯片庭院”培育一颗多核异构 RISC-V SOC种子

    1 文章导览 本文是简要性的导览chipyard官方手册内容,以及安装开发环境需要注意的的一些地方,最后运行几个简单的官方Demo,希望能对RISC-V有兴趣的小伙伴有所启发帮助,官方网址为https ...

  8. 降低芯片设计创新门槛——从互联网成功经验看开源芯片生态发展

    降低芯片设计创新门槛 --从互联网成功经验看开源芯片生态发展 中国科学院计算技术研究所研究员  包云岗 2018年,中国企业遭遇芯片禁售令而陷入困境,中国半导体产业的现状再次引起各界广泛关注.如何尽快 ...

  9. 开源RISC-V 项目Freedom在Arty-7-100T开发板上的实现

    开源RISC-V 项目Freedom在Arty-7-100T开发板上的实现 1.获取Freedom项目源码 Freedom项目开源的地址为https://github.com/sifive/freed ...

最新文章

  1. Linux里find和grep命令
  2. 编程之美2.16 最长递增子序列
  3. array_multisort - 如何保持键值,不重置键值,键名保持不变
  4. flask和vue的冲突问题
  5. jsr250-api_JSON处理的Java API(JSR-353)–流API
  6. linux fsck命令,Linux中fsck命令起什么作用呢?
  7. 如何在Python中便宜地获取大文件的行数?
  8. 图像灰度化的三种方法(matlab、C++、Python实现)
  9. matlab 中ctf,CTF中常见的web
  10. STM32应用文件系统--W25Q256(RTT系统)
  11. 基于matlab的QPSK系统仿真及应用
  12. MPB:青岛大学苏晓泉组-使用Meta-Apo对16S扩增子的微生物组功能信息进行校正
  13. [python爬虫之路day4]:xpath基本知识lxml结合xpath进行数据分析爬取豆瓣电影
  14. 我的 2020 总结:Never Settle
  15. SCZ的3篇有关sam的文章
  16. 浙工大 drcom客户端 嵌入 Linux路由器
  17. Jmeter性能测试云平台搭建
  18. MIUI12或android11找不到QQ文件的问题
  19. python爬取软件内数据_各种数据爬取工具爬虫合集整理
  20. 超详细的Redisson实现分布式锁原理解析

热门文章

  1. 名帖144 行书《兰亭八柱帖》第二册:褚遂良摹兰亭序
  2. 技能梳理37@stm32+按键+光耦+锁存+串行转并行+继电器
  3. 从此有了自己的爱机 - 阉割版“小黑”
  4. 《Python编程:从入门到实践》第十六章:下载数据
  5. Keithley吉时利2182A/Keysight是德34420A纳伏表测量软件-纳伏表软件
  6. Linux下安装ovftool
  7. revit2018注册表删除_Revit软件的彻底卸载方法 注册表卸载 定稿.docx
  8. **服务器的请求与转发_ServletHTTPRequest *
  9. 【产业互联网周报】半导体并购潮持续爆发:Marvell100亿美元收购Inphi;Canalys报告:三季度全球云市场增长33%...
  10. EasyExcel基于一个Sheet模板导出多个Sheet