---
# System prepended metadata

title: FLASH
tags: [CAIDLAB]

---

## Introduction
### FLASH 讀取流程
* [張老師實驗室PPT](https://ncku365-my.sharepoint.com/:p:/g/personal/p76114016_ncku_edu_tw/Ea_77iSdiSxDj-xorKygD2EBaW2TZ9yxoBn50c91MceFfg?e=J8y3le)
#### Srtucture Overview
* 壞掉一次就是壞調整個BLOCK, 所以table是存沒壞掉的BLOCK(B)
![](https://hackmd.io/_uploads/HJ_WXNE8T.png)
* 公式 ： $$Row\_address = B*256+P$$
  * $B : BlockList中block\;number$
  * $P : Page\;number$
* 輸出一次就是一整個page 16K資料出來

## Setup computer for HOST
### Setup computer for OPENSSD
```shell=
// first time
sudo apt install pkg-config libprotobuf-c-dev libtiff5-dev
sudo apt install meson

// Inference         //<use lsblk to find nvm place>
// Example : sudo ./nvme nmc inference /dev/nvme0n1 -f data/0823-2150.tiff 
sudo ./nvme nmc inference /dev/nvme0n1 -f ("filename.tiff" || "filename.model")
```
![圖片](https://hackmd.io/_uploads/B1vt_E4U6.png =x300)

## Write FLASH to specific BRAM
* FLASH Structure
  1 channel = 8 way
  1 way = 265 block
  1 block = 256 page

* Function step
  * Step 1 : Trigger
  * Step 2 : Status_check
  * Step 3 : Transfer
  ![FLASH2BRAM.drawio](https://hackmd.io/_uploads/SJYLcPEIa.png)


### Initial setup
```c=
// Example
// read way:2
// block:1
// page:0
// rowaddres: 1*256 + 0 = 256
int nsc_baseaddress = 0x43CX0000; (channel X)
int ID_register_offset = 0x0;    //useless
int CC_register_offset = 0x3000;
int SP_register_offset = 0x4000;
```
### Trigger
```c=
trigger{
while ( 
    *(nsc_baseaddress + ID_register_offset) & 1 == 0){;}
    *(nsc_baseaddress + SP_register_offset) = 0x1A4    //420 -> trigger_opcode
    *(nsc_baseaddress + SP_register_offset + 4) = 0x00000100    //第幾的way，共8個，以"位置表示"
    *(nsc_baseaddress + SP_register_offset + 8) = 0x100 (rowaddress)    //maxmum 32 bit
    *(nsc_baseaddress + CC_register_offset) = 0x1    //command ready
}
```
### Check
```c=
status_check{   //test if trigger finished
      while ( *(nsc_baseaddress + ID_register_offset) & 1 == 0){;}
    *(nsc_baseaddress + SP_register_offset) = 0x130
    *(nsc_baseaddress + SP_register_offset + 4) = 0x00000100
    *(nsc_baseaddress + SP_register_offset + 8) = statusreport_reg
    *statusreport_reg = 0; (reset)

    *(nsc_baseaddress + CC_register_offset) = 0x1
    }
```
### Trans  fer
```c=
//BRAM 4580_0000 BL 4580_2000 status_report 4580_3000 error_info 4580 4580_3XXX sparedatabuffer
transfer{
      while ( *(nsc_baseaddress + ID_register_offset) & 1 == 0){;}
      *(nsc_baseaddress + SP_register_offset) = 0x338                   //338 -> transfer_opcode
      *(nsc_baseaddress + SP_register_offset + 4) = 0x00000100
      *(nsc_baseaddress + SP_register_offset + 8) = 0x100 (rowaddress)
      *(nsc_baseaddress + SP_register_offset + 12) = *pageDataAddress (target data  buffer address)       //16K page //Bram_address
      *(nsc_baseaddress + SP_register_offset + 16) = *spareDataAddress (target spare  buffer address)     //FW 256 byte metadata => ECC !!!!
      *(nsc_baseaddress + SP_register_offset + 20) = *errorInfoAddress  (target error info address)       //FW
      *(nsc_baseaddress + SP_register_offset + 24) = *completeInfoAddress (target complete info address)  //FW 

      *completeInfoAddress = 0; (reset) //!!Need Check
      *(nsc_baseaddress + CC_register_offset) = 0x1
      assert(*completeInfoAddress == 0xFFA501);
    }
```