实验四 SRAM控制器实验
郭高旭 ggx21@mails.tsinghua.edu.cn 2021010803
实验报告
-
实验过程
sram状态机设计
flowchart LR idle-->|stb_i&&cyc_i&&we_i|write-->write_2-->write_3-->done-->idle idle-->|stb_i&&cyc_i&&!we_i|read-->read_2-->done
各个状态的功能如下:
-
idle:空闲状态,等待读写请求,当接受到master的cyce和stb信号时,根据we信号判断是读还是写
-
read:准备读取数据,按照要求输出 addr, oe_n=0, ce_n=0, we_n=1,根据sel信号选择输出的数据
be_n
-
read_2:把数据存到寄存器中
-
write:准备写入数据,按照要求输出 addr, data, oe_n=1, ce_n=0, we_n=1,根据sel信号选择输出的数据
be_n
-
write_2:输出写使能信号we_n=0
-
write_3:关闭写使能信号
-
done:输出ack信号,表示读写完成,关闭所有使能信号
-
波形仿真
修改 lab4_tb.sv ,设置 dip_sw 随机种子,进行波形仿真,结果如下
-
在线平台测试
在线平台上使用和仿真相同的种子(32`h2)进行测试,数据地址结果和仿真一致
思考题
-
静态存储器的读和写各有什么特点
一般来说,sram需要两周期读,三周期写,因为数据可以直接从存储单元中读取,而写入操作需要额外的周期来准备和执行写入操作。
两周期读:
-
第一个周期:地址传递,选择要读取的存储单元。
-
第二个周期:直接从存储单元中读取数据。
三周期写:
-
第一个周期:地址传递,确定数据要存储的位置。
-
第二个周期:数据准备,将数据加载到内部的写入寄存器。
-
第三个周期:执行实际的写入操作,将数据写入存储单元。
-
什么是ram芯片输出的高阻态,它的作用是什么?
输出为高阻态表示ram接受fpga的输入而屏蔽自身输出,处于read状态。这样一根引线即可实现输入输出,并且避免了一线两端同时输出导致短接。
-
如何实现统一的64位存储器
改变wb_mux实现,不再根据地址选择sram。写入时分别将高低32位和相同地址写入ext和base。读取时从相同地址读取高低32位
实验五 内存串口实验
flowchart TB
IDLE -->read_wait_acktion
subgraph read_data
read_wait_acktion -->|ack|read_wait_check -->|read_checked|read_data_action -->|ack|read_data_done
end
read_data_done --> read_sram_action
read_sram_done-->write_wait_acktion
read_wait_check -->|!read_checked|read_wait_acktion
subgraph write_sram
read_sram_action -->|ack|read_sram_done
end
subgraph write_data
write_wait_acktion -->|ack|write_wait_check -->|write_checked|write_data_action -->|ack|write_data_done
end
write_data_done --> |cnt<10:cnt++|IDLE
write_data_done --> |cnt>=10|DONE
write_wait_check -->|!write_checked|write_wait_acktion</pre>
# 状态描述
1. **IDLE状态**:
- 在IDLE状态下,它等待启动信号。
- 如果启动信号有效,状态机将转移到`READ_WAIT_ACTION`状态以开始串口读写。
2. **READ_WAIT_ACTION状态**:
- 这个状态是为了向串口发送读取请求。
- 等待串口ACK信号的确认请求已发送。
- 如果确认,状态机将进入`READ_WAIT_CHECK`状态。
3. **READ_WAIT_CHECK状态**:
- 这个状态用于检查串口的读状态位。
- 如果读状态位表明串口空闲,状态机将进入`READ_DATA_ACTION`状态。
- 否则,状态机将保持在`READ_WAIT_ACTION`状态,以等待串口变为可用状态。
4. **READ_DATA_ACTION状态**:
- 在这里,状态机向串口发送读取数据请求。
- 等待串口ACK信号以确认请求已发送。
- 一旦确认,状态机将进入`READ_DATA_DONE`状态。
5. **READ_DATA_DONE状态**:
- 在这个状态,状态机从串口接收数据,并将数据存储在`uart_data`寄存器中。
- 然后,状态机准备将数据写入SRAM,进入`READ_SRAM_ACTION`状态。
6. **READ_SRAM_ACTION状态**:
- 这个状态用于将`uart_data`写入到SRAM的地址`temp_sram_addr`中。
- 等待SRAM的ACK信号以确认数据已写入。
- 一旦确认,状态机将进入`READ_SRAM_DONE`状态。
7. **READ_SRAM_DONE状态**:
- 在这个状态,状态机向SRAM发送数据,并等待SRAM的ACK信号以确认写入已完成。
- 一旦确认,状态机将进入`WRITE_WAIT_ACTION`状态。
8. **WRITE_WAIT_ACTION状态**:
- 这个状态用于向串口发送写入数据请求。
- 等待串口ACK信号以确认请求已发送。
- 一旦确认,状态机将进入`WRITE_WAIT_CHECK`状态。
9. **WRITE_WAIT_CHECK状态**:
- 这个状态用于检查串口的写状态位。
- 如果写状态位表明串口空闲,状态机将进入`WRITE_DATA_ACTION`状态。
- 否则,状态机将保持在`WRITE_WAIT_ACTION`状态,以等待串口变为可用状态。
10. **WRITE_DATA_ACTION状态**:
- 这个状态用于将`uart_data`写入串口的数据位。
- 等待串口ACK信号以确认数据已发送。
- 一旦确认,状态机将进入`WRITE_DATA_DONE`状态。
11. **WRITE_DATA_DONE状态**:
- 在这个状态,状态机完成了一轮的读串口、写SRAM、写串口操作。
- 记录操作轮数的变量`count`加1。
- 更新SRAM地址`temp_sram_addr`以准备下一轮操作。
- 如果`count`超过了4'b1000,状态机将进入`DONE`状态,否则返回到`IDLE`状态。
12. **DONE状态**:
- 在这个状态下,状态机停留在DONE状态,表示操作已经完成。
- ### 波形仿真
#### 仿真波形
主要关注了向sram写数据的波形,开始时因为we信号错位导致没有正确结果
![image-20231104222753428](https://gitlab.com/ggx-blog/imglab/uploads/9bca8dd6b3ebb678eb5dfd38294522df/202311042227492.png)
#### 仿真输出
向串口正确输出十个且仅十个字节
![image-20231104222705082](https://gitlab.com/ggx-blog/imglab/uploads/7cc6c3b7db2e173fd953e0b74fd84dad/202311042227108.png)
- ### 云平台实验
拨码开关设为0x80000000(baseram地址)向串口发送10个字节数据,串口输出与内存内容均符合预期
![image-20231104223728319](https://gitlab.com/ggx-blog/imglab/uploads/875d92f901d2e283e2f40264f46e7d41/202311042237345.png)
![image-20231104223718164](https://gitlab.com/ggx-blog/imglab/uploads/fccc834e2876655f3906be9e129d8d61/202311042237192.png)
### 思考题
不一定
`uart-controller`有两个主要的MMIO寄存器:
1. **REG_DATA(地址0x00)**:这个是由Master控制的,这个寄存器用于将数据写入UART控制器的发送缓冲区,以便进行串口通信。
2. **REG_STATUS(地址0x05)**:这个寄存器用于查询UART控制器的状态信息。通过读取该寄存器,Master可以获取`txd_busy`和`rxd_data_ready`等状态信息,以确定发送和接收是否就绪。这个是由controller自己控制与修改的
Q2:
为数码管和拨码开关设置与现有映射不重复的地址,并修改wb-mux使其能识别并选择数码管与拨码开关的地址,使得向wb-master中传入内存地址时,wb-master可以根据其选择数码管或拨码开关。