当前位置:网站首页>Understand chisel language. 24. Chisel sequential circuit (IV) -- detailed explanation of chisel memory
Understand chisel language. 24. Chisel sequential circuit (IV) -- detailed explanation of chisel memory
2022-07-27 09:41:00 【github-3rr0r】
Chisel Sequential circuits ( Four )——Chisel Memory (Memory) Detailed explanation
The last article introduced the implementation of shift register and two commonly used shift registers , It will be very useful in realizing serial communication , It may have some inspiration for the later high-speed interface design . In Digital Design , There are not only registers that can store the state signal of the circuit , Memory (Memory, Or memory , This article is called memory ) You can also save status information , In processor design, memory is also used for storing program code and data , So it's absolutely important . Let's study this article together Chisel Memory implementation in, especially the implementation and initialization of synchronous memory .
Memory and Chisel Synchronous memory in SyncReadMem
Memory can be constructed with a set of registers , such as Chisel In a Vec Of Reg. However, it is too expensive to use registers to realize memory in hardware , So the larger memory structures are built as SRAM(Static Random Access Memory, Static random access memory ). about ASIC It uses memory compiler to build memory . and FPGA Bread on chip memory storage unit (On-chip Memory Block), It's also called block RAM, Block ram . These on-chip memory units can be combined into large memory .FPGA The memory on usually has a read port and a write port , Or two ports that can switch reading and writing at runtime .
FPGA and ASIC It usually supports synchronous memory , Synchronous memory has registers at their inputs , Used to store the read / write port 、 Writing data 、 Write enable signal, etc . This means that the data can only be read after one clock cycle after the address is set . The following figure is a schematic diagram of synchronous memory :

This is a dual port memory , There is a read port , A write port . The read port has an input rdAddr, Read address immediately , And an output rdData, That is, the data read . The write port has three inputs , Write the address (wrAddr)、 The data to be written (wrData) And write enable signal (wrEna). Here's the thing to watch out for , For all input , There is a register in memory for synchronous behavior .
As mentioned earlier, we don't want to use Chisel To realize memory , therefore Chisel In order to support on-chip memory , A special memory constructor is provided SyncReadMem. The following code implements one 1KiB Of memory Memory, And the input and output are byte width with write enable signal :
class Memory() extends Module {
val io = IO(new Bundle {
val rdAddr = Input(UInt(10.W))
val rdData = Output(UInt(8.W))
val wrEnable = Input(Bool())
val wrAddr = Input(UInt(10.W))
val wrData = Input(UInt(8.W))
})
val mem = SyncReadMem(1024, UInt(8.W))
io.rdData := mem.read(io.rdAddr)
when(io.wrEnable) {
mem.write(io.wrAddr, io.wrData)
}
}
You can probably see , Constructors SyncReadMem The generated memory is the synchronous memory with those registers , So we can directly define the relevant input and output ports for the module .SyncReadMem The two parameters of are the size of memory and the data type of memory unit , In the example, it is defined 1024 Bytes of memory , namely 1KiB Of memory . in addition ,mem.read(addr) You can read the address in memory as addr The data of , Empathy mem.write(addr, data) The address in memory can be addr Write data at data. Due to 1024 Indexing memory units requires 10 Address of bit , Left shift read and write addresses are 10 Bit width .
Synchronous memory with read / write forwarding
The above code looks ok , But there is an interesting point , That is, if the same address of the memory is read and written in the same clock cycle , Is the value we read the old value or the new value to be written ? This memory Read while writing (Read-During-Write) Behavior deserves attention , There are three possibilities for the value read :
- Newly written value ;
- Old value ;
- Undefined value ( For example, it may be a combination of bits of the old value and the new value );
FPGA In fact, the possibility depends on FPGA The type of , Sometimes it can be specified . But in the Chisel It is clear in the document of , This read data is Undefined Of .
therefore , If we want to read the newly written value , We can build a forwarding circuit , This circuit can detect whether the read and write addresses are consistent , If it's the same , Just forward the written data to the read data port . The following figure is the schematic diagram of synchronous memory with read-write forwarding :

You can see in the diagram , Read and write addresses will be compared , Then the result is matched with the write enable signal , It is used to select whether the read data is the value of write data or the value read in memory . Again , Because it is synchronous memory , So the selection signal also needs to be written into a register , The read data will be output in the next clock cycle .
The following is synchronous memory with read / write forwarding Chisel Realization :
class ForwardingMemory() extends Module {
val io = IO(new Bundle {
val rdAddr = Input(UInt(10.W))
val rdData = Output(UInt(8.W))
val wrEnable = Input(Bool())
val wrAddr = Input(UInt(10.W))
val wrData = Input(UInt(8.W))
})
val mem = SyncReadMem(1024, UInt(8.W))
val wrDataReg = RegNext(io.wrData)
val doForwardReg = RegNext(io.wrAddr === io.rdAddr && io.wrEnabale)
val memData = mem.read(io.rdAddr)
when(io.wrEnable) {
mem.write(io.wrAddr, io.wrData)
}
io.rdData := Mux(doForwardReg, wrDataReg, memData)
}
The code is still not difficult , We need to put the written data into a register wrDataReg Inside , So that the next clock cycle can be used , One is to adapt synchronous memory , On the other hand, it provides values for reading in the next cycle . At the same time, the code also compares the two input addresses , Read address immediately rdAddr And write address wrAddr, Check the write enable signal wrEnable, Used to judge whether the forwarding conditions are met . This forwarding condition should also be delayed by one clock cycle , So you need the whole register doForwardReg To store whether the forwarding conditions are true . Use one last Mux To select whether the read data is forwarded data or memory read data .
About Chisel Medium Mem
Chisel Another constructor is also provided in Mem, The memory constructed by this constructor is synchronously written 、 Asynchronously read . But this type is FPGA It can't be used directly , The synthesis tool will build it with triggers , Rather than using block RAM. therefore , We should still use SyncReadMem. If you really need to implement asynchronous read behavior , And you use FPGA There are corresponding resources ( For example Xilinx FPGA Inside LUTRAM Structure ), Then you can manually implement and package it as a BlackBox. Generally speaking, suppliers will provide code templates , You can use it directly .
Chisel Memory initialization ( Experimental feature content )
FPGA The memory on can be initialized with binary or hexadecimal initialization files , But note that these files are simple ASCII Text files instead of binary files , The number of lines in the file should be the same as the number of entries in the corresponding memory . Each character in the file represents a value of one or four digits , The binary file is .bin As a file suffix , Each character represents a binary , Hexadecimal files use .hex As a file suffix , Each character represents a four digit binary number .
stay Chisel Can be used in loadMemoryFromFile Function to initialize memory , Usage is as follows :
// You need to use these two packages
import chisel3.util.experimental.loadMemoryFromFile
import firrtl.annotations.MemoryLoadFileType
// Load hex text file into memory
loadMemoryFromFile(mem, "mem.hex", MemoryLoadFileType.Hex)
// Load binary text file into memory
loadMemoryFromFile(mem, "mem.bin", MemoryLoadFileType.Binary)
This loadMemoryFromFile A separate... Will be generated under the folder where the data text file is located Verilog file , The contents of the file are similar to the following code :
module BindsTo_0_Memory(
input clock,
input reset,
input [9:0] io_rdAddr,
output [7:0] io_rdData,
input io_wrEnable,
input [9:0] io_wrAddr,
input [7:0] io_wrData
);
initial begin
$readmemh("mem.hex", Memory.mem);
end
endmodule
bind Memory BindsTo_0_Memory BindsTo_0_Memory_Inst(.*);
This document will be in ChiselTest Work in China , Initialization is also based on Verilog Medium readmemb or readmemh To achieve .
Conclusion
We learned this article Chisel The last part of sequential circuit , Including the implementation and use of synchronous memory , We also talked about the experimental feature of memory initialization . Yes, of course , This is not the only thing about memory , There are also some higher-level content , At the end of this series, I will talk about , Content based on Chisel Official document Explainations, It will cover high-level content not covered in the basic part of this series of tutorials . The next part , We will learn Chisel Some medium-level content in , Respectively for signal processing 、 Finite state machine and communication state machine , It will involve Chisel Some medium order properties of , Useful in digital design .
边栏推荐
- Fundamentals of Materials Engineering - key points
- 2022 software test interview questions 200 big factory interview true questions brushed to get 10K positions
- 七月集训(第12天) —— 链表
- MOS drive in motor controller
- Sentinel 万字教程 | 文末送书
- July training (day 07) - hash table
- Read the paper learning to measure changes: full revolutionary Siamese metric networks for scene change detect
- How to use tdengine sink connector?
- July training (the 26th day) - and check the collection
- Nacos is used as a registration center
猜你喜欢

How to install cpolar intranet penetration on raspberry pie

Run uni app project in hbuilder wechat applet

What age are you still using date

Esp8266 Arduino programming example PWM

35 spark streaming backpressure mechanism, spark data skew solution and kylin's brief introduction

Esp8266 Arduino programming example ADC

拟搬迁!211中国石油大学(华东)新校区,正式启用!

吃透Chisel语言.22.Chisel时序电路(二)——Chisel计数器(Counter)详解:计数器、定时器和脉宽调制

Quick apply custom progress bar

安装了HAL库如何恢复原来的版本
随机推荐
NCCL (NVIDIA Collective Communications Library)
曝光一位出身寒门的技术大佬
Towards the peak of life
A ride into Qinchuan -- a brief talk on how beego Autorouter works
Google Earth engine app - maximum image synthesis analysis using S2 image
Esp8266 Arduino programming example - interrupt
【树莓派】Box相关手册-4 Web代理
July training (day 06) - sliding window
[Wuhan University of technology] information sharing for the preliminary and second examinations of postgraduate entrance examination
NCCL 集合通信--Collective Operations
July training (day 19) - binary tree
How to install cpolar intranet penetration on raspberry pie
Eureka delayed registration of a pit
命令提示符启动不了mysql,提示发生系统错误 5。拒绝访问。解决办法
July training (day 03) - sorting
[cloud native] how can I compete with this database?
Esp8266 Arduino programming example ADC
Community attribute of BGP
吃透Chisel语言.25.Chisel进阶之输入信号处理(一)——异步输入与去抖动
内存墙简介