Merge pull request #147 from retroSoC/dev

Dev
This commit is contained in:
Yuchi Miao authored and GitHub committed 2026-01-18 13:35:04 +08:00
commit dc6d853ebb
57 files changed
+1139 -16847

No files matched your search

+3 -3
View File
@@ -1,7 +1,7 @@
SOC ?= MINI
SIMU ?= VCS
SYNTH ?= NONE
TIMI ?= OPENSTA
TIMI ?= NONE
# HW
PDK ?= IHP130
@@ -44,8 +44,8 @@ $(info SOC [TINY, MINI]: $(SOC))
$(info CORE [PICORV32, HAZARD3, MDD]: $(CORE))
$(info IP [NONE, MDD]: $(IP))
$(info SIMU [VCS, VERILATOR]: $(SIMU))
$(info SYNTH [YOSYS, DC]: $(SYNTH))
$(info TIMI [OPENSTA, ISTA]: $(TIMI))
$(info SYNTH [NONE, YOSYS, DC]: $(SYNTH))
$(info TIMI [NONE, OPENSTA, ISTA]: $(TIMI))
$(info PDK [ICS55, IHP130, SKY130, GF180]: $(PDK))
$(info HAVE_PLL [YES, NO]: $(HAVE_PLL))
$(info HAVE_SRAM_IF [YES, NO]: $(HAVE_SRAM_IF))
+35 -48
View File
@@ -12,7 +12,7 @@
#define HW_CORE "none"
#endif
#define CPU_FREQ 48 // unit: MHz
#define CPU_FREQ 72 // unit: MHz
#define UART_BPS 921600 // unit: bps
#define PSRAM_NUM 4
#define PSRAM_SCLK_MIN_FREQ 12 // unit: MHz
@@ -35,10 +35,12 @@
#define TF_CARD_OFFST (uint32_t)0x40000000
// gpio
#define reg_gpio_data (*(volatile uint32_t*)0x10000000)
#define reg_gpio_oe (*(volatile uint32_t*)0x10000004)
#define reg_gpio_pun (*(volatile uint32_t*)0x10000008)
#define reg_gpio_pdn (*(volatile uint32_t*)0x1000000c)
#define reg_gpio_oe (*(volatile uint32_t*)0x10000000)
#define reg_gpio_cs (*(volatile uint32_t*)0x10000004)
#define reg_gpio_pu (*(volatile uint32_t*)0x10000008)
#define reg_gpio_pd (*(volatile uint32_t*)0x1000000c)
#define reg_gpio_do (*(volatile uint32_t*)0x10000010)
#define reg_gpio_di (*(volatile uint32_t*)0x10000014)
// uart1
#define reg_uart0_clkdiv (*(volatile uint32_t*)0x10001000)
#define reg_uart0_data (*(volatile uint32_t*)0x10001004)
@@ -86,7 +88,7 @@
#define reg_onewire_txdata (*(volatile uint32_t*)0x10008010)
#define reg_onewire_ctrl (*(volatile uint32_t*)0x10008014)
#define reg_onewire_status (*(volatile uint32_t*)0x10008018)
// qspi0
// xpi
#define reg_qspi0_mode (*(volatile uint32_t*)0x10009000)
#define reg_qspi0_nss (*(volatile uint32_t*)0x10009004)
#define reg_qspi0_clkdiv (*(volatile uint32_t*)0x10009008)
@@ -112,6 +114,7 @@
#define reg_qspi0_hlvlen (*(volatile uint32_t*)0x10009058)
#define reg_qspi0_start (*(volatile uint32_t*)0x1000905C)
#define reg_qspi0_status (*(volatile uint32_t*)0x10009060)
#define reg_qspi0_mmmode (*(volatile uint32_t*)0x10009064)
// dma(32b xfer, hardware trigger by I2S fifo, QSPI fifo)
#define reg_dma_mode (*(volatile uint32_t*)0x1000A000)
#define reg_dma_srcaddr (*(volatile uint32_t*)0x1000A004)
@@ -136,6 +139,8 @@
#define reg_clint_mtimecmph (*(volatile uint32_t*)0x1000C00C)
#define reg_clint_msip (*(volatile uint32_t*)0x1000C010)
#define reg_clint_clkdiv (*(volatile uint32_t*)0x1000C014)
// sdram
#define reg_sdram_cfg (*(volatile uint32_t*)0x1000D000)
// apb
// archinfo
#define reg_archinfo_sys (*(volatile uint32_t*)0x20000000)
@@ -165,51 +170,33 @@
#define reg_ps2_ctrl (*(volatile uint32_t*)0x20004000)
#define reg_ps2_data (*(volatile uint32_t*)0x20004004)
#define reg_ps2_stat (*(volatile uint32_t*)0x20004008)
// i2c1
#define reg_i2c1_ctrl (*(volatile uint32_t*)0x20005000)
#define reg_i2c1_pscr (*(volatile uint32_t*)0x20005004)
#define reg_i2c1_txr (*(volatile uint32_t*)0x20005008)
#define reg_i2c1_rxr (*(volatile uint32_t*)0x2000500c)
#define reg_i2c1_cmd (*(volatile uint32_t*)0x20005010)
#define reg_i2c1_sr (*(volatile uint32_t*)0x20005014)
// qspi1
#define reg_qspi1_status (*(volatile uint32_t*)0x20006000)
#define reg_qspi1_clkdiv (*(volatile uint32_t*)0x20006004)
#define reg_qspi1_cmd (*(volatile uint32_t*)0x20006008)
#define reg_qspi1_adr (*(volatile uint32_t*)0x2000600c)
#define reg_qspi1_len (*(volatile uint32_t*)0x20006010)
#define reg_qspi1_dum (*(volatile uint32_t*)0x20006014)
#define reg_qspi1_txfifo (*(volatile uint32_t*)0x20006018)
#define reg_qspi1_rxfifo (*(volatile uint32_t*)0x20006020)
#define reg_qspi1_intcfg (*(volatile uint32_t*)0x20006024)
#define reg_qspi1_intsta (*(volatile uint32_t*)0x20006028)
// rtc
#define reg_rtc_ctrl (*(volatile uint32_t*)0x20007000)
#define reg_rtc_pscr (*(volatile uint32_t*)0x20007004)
#define reg_rtc_cnt (*(volatile uint32_t*)0x20007008)
#define reg_rtc_alrm (*(volatile uint32_t*)0x2000700C)
#define reg_rtc_ista (*(volatile uint32_t*)0x20007010)
#define reg_rtc_ssta (*(volatile uint32_t*)0x20007014)
#define reg_rtc_ctrl (*(volatile uint32_t*)0x20005000)
#define reg_rtc_pscr (*(volatile uint32_t*)0x20005004)
#define reg_rtc_cnt (*(volatile uint32_t*)0x20005008)
#define reg_rtc_alrm (*(volatile uint32_t*)0x2000500C)
#define reg_rtc_ista (*(volatile uint32_t*)0x20005010)
#define reg_rtc_ssta (*(volatile uint32_t*)0x20005014)
// wdg
#define reg_wdg_ctrl (*(volatile uint32_t*)0x20008000)
#define reg_wdg_pscr (*(volatile uint32_t*)0x20008004)
#define reg_wdg_cnt (*(volatile uint32_t*)0x20008008)
#define reg_wdg_cmp (*(volatile uint32_t*)0x2000800C)
#define reg_wdg_stat (*(volatile uint32_t*)0x20008010)
#define reg_wdg_key (*(volatile uint32_t*)0x20008014)
#define reg_wdg_feed (*(volatile uint32_t*)0x20008018)
#define reg_wdg_ctrl (*(volatile uint32_t*)0x20006000)
#define reg_wdg_pscr (*(volatile uint32_t*)0x20006004)
#define reg_wdg_cnt (*(volatile uint32_t*)0x20006008)
#define reg_wdg_cmp (*(volatile uint32_t*)0x2000600C)
#define reg_wdg_stat (*(volatile uint32_t*)0x20006010)
#define reg_wdg_key (*(volatile uint32_t*)0x20006014)
#define reg_wdg_feed (*(volatile uint32_t*)0x20006018)
// crc
#define reg_crc_ctrl (*(volatile uint32_t*)0x20009000)
#define reg_crc_init (*(volatile uint32_t*)0x20009004)
#define reg_crc_xorv (*(volatile uint32_t*)0x20009008)
#define reg_crc_data (*(volatile uint32_t*)0x2000900C)
#define reg_crc_stat (*(volatile uint32_t*)0x20009010)
// tim
#define reg_tim3_ctrl (*(volatile uint32_t*)0x2000A000)
#define reg_tim3_pscr (*(volatile uint32_t*)0x2000A004)
#define reg_tim3_cnt (*(volatile uint32_t*)0x2000A008)
#define reg_tim3_cmp (*(volatile uint32_t*)0x2000A00C)
#define reg_tim3_stat (*(volatile uint32_t*)0x2000A010)
#define reg_crc_ctrl (*(volatile uint32_t*)0x20007000)
#define reg_crc_init (*(volatile uint32_t*)0x20007004)
#define reg_crc_xorv (*(volatile uint32_t*)0x20007008)
#define reg_crc_data (*(volatile uint32_t*)0x2000700C)
#define reg_crc_stat (*(volatile uint32_t*)0x20007010)
// tim3
#define reg_tim3_ctrl (*(volatile uint32_t*)0x20008000)
#define reg_tim3_pscr (*(volatile uint32_t*)0x20008004)
#define reg_tim3_cnt (*(volatile uint32_t*)0x20008008)
#define reg_tim3_cmp (*(volatile uint32_t*)0x2000800C)
#define reg_tim3_stat (*(volatile uint32_t*)0x20008010)
// user ip design(example)
#define reg_user_ip_reg0 (*(volatile uint32_t*)0x2000F000)
#define reg_user_ip_reg1 (*(volatile uint32_t*)0x2000F004)
-25
View File
@@ -4,21 +4,6 @@
#define I2C0_XFER_WR 0b10
#define I2C0_XFER_RD 0b11
#define I2C1_START ((uint32_t)0x80)
#define I2C1_STOP ((uint32_t)0x40)
#define I2C1_READ ((uint32_t)0x20)
#define I2C1_WRITE ((uint32_t)0x10)
#define I2C1_START_READ ((uint32_t)0xA0)
#define I2C1_START_WRITE ((uint32_t)0x90)
#define I2C1_STOP_READ ((uint32_t)0x60)
#define I2C1_STOP_WRITE ((uint32_t)0x50)
#define I2C1_STATUS_RXACK ((uint32_t)0x80) // (1 << 7)
#define I2C1_STATUS_BUSY ((uint32_t)0x40) // (1 << 6)
#define I2C1_STATUS_AL ((uint32_t)0x20) // (1 << 5)
#define I2C1_STATUS_TIP ((uint32_t)0x02) // (1 << 1)
#define I2C1_STATUS_IF ((uint32_t)0x01) // (1 << 0)
#define I2C_DEV_ADDR_8BIT 0
#define I2C_DEV_ADDR_16BIT 1
@@ -26,14 +11,4 @@ void i2c0_init(uint8_t clkdiv);
void i2c0_wr_nbyte(uint8_t dev_addr, uint16_t reg_addr, uint8_t type, uint8_t num, uint8_t *data);
void i2c0_rd_nbyte(uint8_t dev_addr, uint16_t reg_addr, uint8_t type, uint8_t num, uint8_t *data);
void i2c1_init();
uint32_t i2c1_get_ack();
uint32_t i2c1_busy();
void i2c1_wr_start(uint32_t slv_addr);
void i2c1_rd_start(uint32_t slv_addr);
void i2c1_write(uint8_t val);
uint32_t i2c1_read(uint32_t cmd);
void i2c1_wr_nbyte(uint8_t slv_addr, uint16_t reg_addr, uint8_t type, uint8_t num, uint8_t *data);
void i2c1_rd_nbyte(uint8_t slv_addr, uint16_t reg_addr, uint8_t type, uint8_t num, uint8_t *data);
#endif
+2 -2
View File
@@ -3,8 +3,8 @@
#include <stdint.h>
#define lcd_dc_clr (reg_gpio_data = (uint32_t)0b000)
#define lcd_dc_set (reg_gpio_data = (uint32_t)0b100)
#define lcd_dc_clr (reg_gpio_do = (uint32_t)0b000)
#define lcd_dc_set (reg_gpio_do = (uint32_t)0b100)
#define USE_HORIZONTAL 2
-7
View File
@@ -1,7 +1,6 @@
#ifndef TINYQSPI_H__
#define TINYQSPI_H__
#define USE_QSPI0_DEV
#define USE_QSPI0_DMA
typedef struct {
@@ -45,11 +44,5 @@ void qspi0_wr_dat16(uint16_t dat);
void qspi0_wr_data32(uint32_t* dat, uint32_t len);
void qspi0_dma_xfer(uint32_t addr, uint32_t len);
void qspi1_init();
void qspi1_wr_dat8(uint8_t dat);
void qspi1_wr_data16(uint16_t dat);
void qspi1_wr_data32(uint32_t* dat, uint32_t len);
void qspi_dev_init();
#endif
+11 -9
View File
@@ -62,6 +62,8 @@ void app_info() {
printf("[%d]: %-15s %-12s %-12s %s\n", i, user_core_info[i].name, user_core_info[i].isa, user_core_info[i].maintainer, user_core_info[i].repo);
}
#endif
#ifdef IP_MDD
printf("\nUser IPs:\n");
uint32_t ip_size = sizeof(user_ip_info)/sizeof(user_ip_info[0]);
printf(" %-15s %-12s %-12s %s\n", "[name]", "[isa]", "[maintainer]", "[repo]");
@@ -70,6 +72,7 @@ void app_info() {
else printf(" ");
printf("[%d]: %-15s %-12s %-12s %s\n", i, user_ip_info[i].name, user_ip_info[i].isa, user_ip_info[i].maintainer, user_ip_info[i].repo);
}
#endif
printf("\nSoftware:\n");
@@ -83,30 +86,29 @@ void app_info() {
printf(" NMI IP MMIO: @[0x%08x-0x%08x] %dMiB\n", NMI_MEM_START, NMI_MEM_START + NMI_MEM_OFFST - 1, NMI_MEM_OFFST / 1024 / 1024);
printf(" APB IP MMIO: @[0x%08x-0x%08x] %dMiB\n", APB_MEM_START, APB_MEM_START + APB_MEM_OFFST - 1, APB_MEM_OFFST / 1024 / 1024);
printf(" On-chip RAM: @[0x%08x-0x%08x] %dKiB\n", SRAM_MEM_START, SRAM_MEM_START + SRAM_MEM_OFFST - 1, SRAM_MEM_OFFST / 1024);
printf(" Extern PSRAM: @[0x%08x-0x%08x] %dMiB(%dx8MiB)\n", PSRAM_MEM_START, PSRAM_MEM_START + PSRAM_MEM_OFFST - 1, 8 * PSRAM_NUM, PSRAM_NUM);
printf(" QSPI0 MMIO: @[0x%08x-0x%08x] %dMiB\n", QSPI_MEM_START, QSPI_MEM_START + QSPI_MEM_OFFST - 1, QSPI_MEM_OFFST / 1024 / 1024);
printf(" Off-chip PSRAM: @[0x%08x-0x%08x] %dMiB(%dx8MiB)\n", PSRAM_MEM_START, PSRAM_MEM_START + PSRAM_MEM_OFFST - 1, 8 * PSRAM_NUM, PSRAM_NUM);
printf(" XPI MMIO: @[0x%08x-0x%08x] %dMiB\n", QSPI_MEM_START, QSPI_MEM_START + QSPI_MEM_OFFST - 1, QSPI_MEM_OFFST / 1024 / 1024);
printf(" TF Card MMIO: @[0x%08x-0x%08x] %dGiB\n\n", TF_CARD_START, TF_CARD_START + TF_CARD_OFFST - 1, TF_CARD_OFFST / 1024 / 1024 / 1024);
printf("Memory Map IO Device:\n");
printf(" 8 x GPIO @0x%x\n", &reg_gpio_data);
printf(" 8 x GPIO @0x%x\n", &reg_gpio_oe);
printf(" 1 x UART0 @0x%x\n", &reg_uart0_clkdiv);
printf(" 2 x TIMER(0,1) @0x%x,0x%x\n", &reg_tim0_cfg, &reg_tim1_cfg);
printf(" 1 x PSRAM @0x%x\n", &reg_psram_wait);
printf(" 1 x SPISD @0x%x\n", &reg_spisd_mode);
printf(" 1 x I2C0 @0x%x\n", &reg_i2c0_clkdiv);
printf(" 1 x SPISD/SDIO @0x%x\n", &reg_spisd_mode);
printf(" 1 x I2C @0x%x\n", &reg_i2c0_clkdiv);
printf(" 1 x I2S @0x%x\n", &reg_i2s_mode);
printf(" 1 x ONEWIRE @0x%x\n", &reg_onewire_clkdiv);
printf(" 1 x QSPI0 @0x%x\n", &reg_qspi0_mode);
printf(" 1 x XPI @0x%x\n", &reg_qspi0_mode);
printf(" 1 x DMA @0x%x\n", &reg_dma_mode);
printf(" 1 x SYSCTRL @0x%x\n", &reg_sysctrl_coresel);
printf(" 1 x CLINT @0x%x\n", &reg_clint_clkdiv);
printf(" 1 x CLINT @0x%x\n", &reg_clint_mtimel);
printf(" 1 x SDRAM @0x%x\n", &reg_sdram_cfg);
printf(" 1 x ARCHINFO @0x%x\n", &reg_archinfo_sys);
printf(" 1 x RNG @0x%x\n", &reg_rng_ctrl);
printf(" 1 x UART1(ADV) @0x%x\n", &reg_uart1_lcr);
printf(" 4 x PWM @0x%x\n", &reg_pwm_ctrl);
printf(" 1 x PS2 @0x%x\n", &reg_ps2_ctrl);
printf(" 1 x I2C1(ADV) @0x%x\n", &reg_i2c1_ctrl);
printf(" 1 x QSPI1 @0x%x\n", &reg_qspi1_status);
printf(" 1 x RTC @0x%x\n", &reg_rtc_ctrl);
printf(" 1 x WDG @0x%x\n", &reg_wdg_ctrl);
printf(" 1 x CRC @0x%x\n", &reg_crc_ctrl);
+18 -27
View File
@@ -13,47 +13,38 @@ void ip_gpio_test(int argc, char **argv) {
reg_gpio_oe = (uint32_t)0b1111;
printf("[GPIO OE] %x\n", reg_gpio_oe);
printf("[GPIO DATA] %x\n", reg_gpio_data);
reg_gpio_data = (uint32_t)0xffff;
printf("[GPIO DATA] %x\n", reg_gpio_data);
printf("[GPIO DATA] %x\n", reg_gpio_do);
reg_gpio_do = (uint32_t)0xffff;
printf("[GPIO DATA] %x\n", reg_gpio_do);
reg_gpio_data = (uint32_t)0x0000;
printf("[GPIO DATA] %x\n", reg_gpio_data);
reg_gpio_do = (uint32_t)0x0000;
printf("[GPIO DATA] %x\n", reg_gpio_do);
printf("led output test\n");
for (int i = 0; i < 50; ++i)
{
for (int i = 0; i < 50; ++i) {
delay_ms(300);
if (reg_gpio_data == 0b00)
reg_gpio_data = (uint32_t)0b01;
else
reg_gpio_data = (uint32_t)0b00;
if (reg_gpio_do == 0b00) reg_gpio_do = (uint32_t)0b01;
else reg_gpio_do = (uint32_t)0b00;
}
reg_gpio_data = (uint32_t)0b00;
reg_gpio_do = (uint32_t)0b00;
printf("key input test\n"); // need extn board
reg_gpio_oe = (uint32_t)0b1101;
printf("[GPIO OE] %x\n", reg_gpio_oe);
printf("[GPIO DATA] %x\n", reg_gpio_data);
for (int i = 0; i < 60; ++i)
{
printf("[GPIO DATA] %x\n", reg_gpio_do);
return;
for (int i = 0; i < 60; ++i) {
uint32_t led_val = 0b00;
if (((reg_gpio_data & 0b10) >> 1) == 0b0)
{
if (((reg_gpio_do & 0b10) >> 1) == 0b0) {
delay_ms(100); // debouncing
if (((reg_gpio_data & 0b10) >> 1) == 0b0)
{
if (((reg_gpio_do & 0b10) >> 1) == 0b0) {
printf("key detect\n");
if (led_val == 0b00)
{
if (led_val == 0b00) {
led_val = 0b01;
reg_gpio_data = led_val;
}
else
{
reg_gpio_do = led_val;
} else {
led_val = 0b00;
reg_gpio_data = led_val;
reg_gpio_do = led_val;
}
}
}
-91
View File
@@ -32,94 +32,3 @@ void i2c0_rd_nbyte(uint8_t dev_addr, uint16_t reg_addr, uint8_t type, uint8_t nu
data[i] = reg_i2c0_rxdata;
}
}
void i2c1_init() {
reg_i2c1_ctrl = (uint32_t)0;
reg_i2c1_pscr = (uint32_t)99; // 50MHz / (5 * 100KHz) - 1
printf("CTRL: %d PSCR: %d\n", reg_i2c1_ctrl, reg_i2c1_pscr);
reg_i2c1_ctrl = (uint32_t)0b10000000; // core en
}
uint32_t i2c1_get_ack() {
while ((reg_i2c1_sr & I2C1_STATUS_TIP) == 0); // need TIP go to 1
while ((reg_i2c1_sr & I2C1_STATUS_TIP) != 0); // and then go back to 0
return !(reg_i2c1_sr & I2C1_STATUS_RXACK); // invert since signal is active low
}
uint32_t i2c1_busy() {
return ((reg_i2c1_sr & I2C1_STATUS_BUSY) == I2C1_STATUS_BUSY);
}
void i2c1_wr_start(uint32_t slv_addr) {
reg_i2c1_txr = slv_addr;
reg_i2c1_cmd = I2C1_START_WRITE;
if (!i2c1_get_ack()) printf("[wr start]no ack recv\n");
}
void i2c1_rd_start(uint32_t slv_addr) {
do {
reg_i2c1_txr = slv_addr;
reg_i2c1_cmd = I2C1_START_WRITE;
}while (!i2c1_get_ack());
}
void i2c1_write(uint8_t val) {
reg_i2c1_txr = val;
reg_i2c1_cmd = I2C1_WRITE;
if (!i2c1_get_ack()) printf("[i2c write]no ack recv\n");
// do {
// reg_i2c1_txr = val;
// reg_i2c1_cmd = I2C1_WRITE;
// } while(!i2c_get_ack());
}
uint32_t i2c1_read(uint32_t cmd) {
reg_i2c1_cmd = cmd;
if (!i2c1_get_ack()) printf("[i2c read]no ack recv\n");
return reg_i2c1_rxr;
}
void i2c1_stop() {
reg_i2c1_cmd = I2C1_STOP;
while(i2c1_busy());
}
void i2c1_wr_nbyte(uint8_t slv_addr, uint16_t reg_addr, uint8_t type, uint8_t num, uint8_t *data) {
// i2c_wr_start(slv_addr);
i2c1_rd_start(slv_addr);
if(type == I2C_DEV_ADDR_16BIT) {
i2c1_write((uint8_t)((reg_addr >> 8) & 0xFF));
i2c1_write((uint8_t)(reg_addr & 0xFF));
} else {
i2c1_write((uint8_t)(reg_addr & 0xFF));
}
for(int i = 0; i < num; ++i) {
i2c1_write(*data);
++data;
}
i2c1_stop();
}
void i2c1_rd_nbyte(uint8_t slv_addr, uint16_t reg_addr, uint8_t type, uint8_t num, uint8_t *data) {
i2c1_rd_start(slv_addr);
if(type == I2C_DEV_ADDR_16BIT) {
i2c1_write((uint8_t)((reg_addr >> 8) & 0xFF));
i2c1_write((uint8_t)(reg_addr & 0xFF));
} else {
i2c1_write((uint8_t)(reg_addr & 0xFF));
}
i2c1_stop();
i2c1_wr_start(slv_addr + 1);
for (int i = 0; i < num; ++i) {
if (i == num - 1) data[i] = i2c1_read(I2C1_STOP_READ);
else data[i] = i2c1_read(I2C1_READ);
}
}
-16
View File
@@ -48,38 +48,22 @@ static uint32_t rgb_color[][32] = {
void lcd_wr_dc_cmd(uint8_t cmd) {
lcd_dc_clr;
#ifdef USE_QSPI0_DEV
qspi0_wr_dat8(cmd);
#else
qspi1_wr_dat8(cmd);
#endif
}
void lcd_wr_dc_data8(uint8_t dat) {
lcd_dc_set;
#ifdef USE_QSPI0_DEV
qspi0_wr_dat8(dat);
#else
qspi1_wr_dat8(dat);
#endif
}
void lcd_wr_dc_data16(uint16_t dat) {
lcd_dc_set;
#ifdef USE_QSPI0_DEV
qspi0_wr_dat16(dat);
#else
qspi1_wr_data16(dat);
#endif
}
void lcd_wr_data32(uint32_t* dat, uint32_t len) {
lcd_dc_set;
#ifdef USE_QSPI0_DEV
qspi0_wr_data32(dat, len);
#else
qspi1_wr_data32(dat, len);
#endif
}
-39
View File
@@ -179,43 +179,7 @@ void qspi0_dma_xfer(uint32_t addr, uint32_t len) {
reg_qspi0_datlen = (uint32_t)1;
}
void qspi1_init() {
reg_gpio_oe = (uint32_t)0b100;
reg_qspi1_status = (uint32_t)0b10000;
reg_qspi1_status = (uint32_t)0b00000;
reg_qspi1_intcfg = (uint32_t)0b00000;
reg_qspi1_dum = (uint32_t)0;
reg_qspi1_clkdiv = (uint32_t)0; // sck = apb_clk/2(div+1)
}
void qspi1_wr_dat8(uint8_t dat) {
uint32_t wdat = ((uint32_t)dat) << 24;
// spi_set_datalen(8);
reg_qspi1_len = 0x80000;
// spi_write_fifo(&wdata, 8);
reg_qspi1_txfifo = wdat;
// spi_start_transaction(SPI_CMD_WR, SPI_CSN0);
reg_qspi1_status = 258;
while ((reg_qspi1_status & 0xFFFF) != 1);
}
void qspi1_wr_data16(uint16_t dat) {
uint32_t wdat = ((uint32_t)dat) << 16;
reg_qspi1_len = 0x100000; // NOTE: 16bits
reg_qspi1_txfifo = wdat;
reg_qspi1_status = 258;
while ((reg_qspi1_status & 0xFFFF) != 1);
}
void qspi1_wr_data32(uint32_t* dat, uint32_t len) {
reg_qspi1_len = (32 * len) << 16;
for(uint32_t i = 0; i < len; ++i) reg_qspi1_txfifo = dat[i];
reg_qspi1_status = 258;
while ((reg_qspi1_status & 0xFFFF) != 1);
}
void qspi_dev_init() {
#ifdef USE_QSPI0_DEV
QSPI0_InitStruct_t qspi0 = {
(uint32_t)0,
(uint32_t)0b0001, // fpga
@@ -235,7 +199,4 @@ void qspi_dev_init() {
(uint32_t)0,
(uint32_t)1, (uint32_t)1, (uint32_t)1
);
#else
qspi1_init();
#endif
}
-82
View File
@@ -1,82 +0,0 @@
`timescale 1ns / 10ps
`include "spi_defines.v"
module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge,cpol);
parameter Tp = 1;
input clk_in; // input clock (system clock)
input rst; // reset
input enable; // clock enable
input go; // start transfer
input last_clk; // last clock
input [`SPI_DIVIDER_LEN-1:0] divider; // clock divider (output clock is divided by this value)
output clk_out; // output clock
output pos_edge; // pulse marking positive edge of clk_out
output neg_edge; // pulse marking negative edge of clk_out
input cpol;
reg clk_out;
reg pos_edge;
reg neg_edge;
reg [`SPI_DIVIDER_LEN-1:0] cnt; // clock counter
wire cnt_zero; // conter is equal to zero
wire cnt_one; // conter is equal to one
assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}};
assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
// Counter counts half period
always @(posedge clk_in or posedge rst)
begin
if(rst)
cnt <= #Tp {`SPI_DIVIDER_LEN{1'b1}};
else
begin
if(!enable || cnt_zero)
cnt <= #Tp divider;
else
cnt <= #Tp cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
end
end
/*
// clk_out is asserted every other half period
always @(posedge clk_in or posedge rst)
begin
clk_out <= 1'b1;
if((rst || !enable) && cpol)
clk_out <= #Tp 1'b1;
else if((rst || !enable) && !cpol)
clk_out <= #Tp 1'b0;
else
clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
end
*/
// clk_out is asserted every other half period
always @(posedge clk_in or posedge rst)
begin
if(rst)
clk_out <= #Tp 1'b0;
else
clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
end
// Pos and neg edge signals
always @(posedge clk_in or posedge rst)
begin
if(rst)
begin
pos_edge <= #Tp 1'b0;
neg_edge <= #Tp 1'b0;
end
else
begin
pos_edge <= #Tp (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
neg_edge <= #Tp (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
end
end
endmodule
-119
View File
@@ -1,119 +0,0 @@
// Code your design here
`timescale 1ns / 10ps
`define SPI_DIVIDER_LEN_8
//`define SPI_DIVIDER_LEN_16
//`define SPI_DIVIDER_LEN_24
//`define SPI_DIVIDER_LEN_32
`ifdef SPI_DIVIDER_LEN_8
`define SPI_DIVIDER_LEN 8 // Can be set from 1 to 8
`endif
`ifdef SPI_DIVIDER_LEN_16
`define SPI_DIVIDER_LEN 16 // Can be set from 9 to 16
`endif
`ifdef SPI_DIVIDER_LEN_24
`define SPI_DIVIDER_LEN 24 // Can be set from 17 to 24
`endif
`ifdef SPI_DIVIDER_LEN_32
`define SPI_DIVIDER_LEN 32 // Can be set from 25 to 32
`endif
//
// Maximum nuber of bits that can be send/received at once.
// Use SPI_MAX_CHAR for fine tuning the exact number, when using
// SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8.
//
`define SPI_MAX_CHAR_128
//`define SPI_MAX_CHAR_64
//`define SPI_MAX_CHAR_32
//`define SPI_MAX_CHAR_24
//`define SPI_MAX_CHAR_16
//`define SPI_MAX_CHAR_8
`ifdef SPI_MAX_CHAR_128
`define SPI_MAX_CHAR 128 //
`define SPI_CHAR_LEN_BITS 7
`endif
`ifdef SPI_MAX_CHAR_64
`define SPI_MAX_CHAR 64 // Can only be set to 64
`define SPI_CHAR_LEN_BITS 6
`endif
`ifdef SPI_MAX_CHAR_32
`define SPI_MAX_CHAR 32 // Can be set from 25 to 32
`define SPI_CHAR_LEN_BITS 5
`endif
`ifdef SPI_MAX_CHAR_24
`define SPI_MAX_CHAR 24 // Can be set from 17 to 24
`define SPI_CHAR_LEN_BITS 5
`endif
`ifdef SPI_MAX_CHAR_16
`define SPI_MAX_CHAR 16 // Can be set from 9 to 16
`define SPI_CHAR_LEN_BITS 4
`endif
`ifdef SPI_MAX_CHAR_8
`define SPI_MAX_CHAR 8 // Can be set from 1 to 8
`define SPI_CHAR_LEN_BITS 3
`endif
//
// Number of device select signals. Use SPI_SS_NB for fine tuning the
// exact number.
//
`define SPI_SS_NB_8
//`define SPI_SS_NB_16
//`define SPI_SS_NB_24
//`define SPI_SS_NB_32
`ifdef SPI_SS_NB_8
`define SPI_SS_NB 8 // Can be set from 1 to 8
`endif
`ifdef SPI_SS_NB_16
`define SPI_SS_NB 16 // Can be set from 9 to 16
`endif
`ifdef SPI_SS_NB_24
`define SPI_SS_NB 24 // Can be set from 17 to 24
`endif
`ifdef SPI_SS_NB_32
`define SPI_SS_NB 32 // Can be set from 25 to 32
`endif
//
// Bits of WISHBONE address used for partial decoding of SPI registers.
//
`define SPI_OFS_BITS 4:2
//
// Register offset
//
`define SPI_RX_0 0
`define SPI_RX_1 1
`define SPI_RX_2 2
`define SPI_RX_3 3
`define SPI_TX_0 0
`define SPI_TX_1 1
`define SPI_TX_2 2
`define SPI_TX_3 3
`define SPI_CTRL 4
`define SPI_DEVIDE 5
`define SPI_SS 6
//
// Number of bits in ctrl register
//
//`define SPI_CTRL_BIT_NB 14
`define SPI_CTRL_BIT_NB 32 //cuckoo
//
// Control register bit position
//
`define SPI_CTRL_SS 31:24 //cuckoo
`define SPI_CTRL_DIV 23:16 //cuckoo
`define SPI_CTRL_CPOL 15 //cuckoo(clock polar)
`define SPI_CTRL_RD_ENDIAN 14 //cuckoo
`define SPI_CTRL_ASS 13
`define SPI_CTRL_IE 12
`define SPI_CTRL_LSB 11
`define SPI_CTRL_TX_NEGEDGE 10 //CPHA(clock phase)
`define SPI_CTRL_RX_NEGEDGE 9
`define SPI_CTRL_GO 8
`define SPI_CTRL_RES_1 7
`define SPI_CTRL_CHAR_LEN 6:0
-240
View File
@@ -1,240 +0,0 @@
`define SPI_CTL_DIV_4 32'h00010000 //23:16 (divide by 4)
`define SPI_CTL_DIV_2 32'h00000000 //23:16 (divide by 2)
`define SPI_CTL_SS 32'h01000000 //31:24
`define SPI_CTL_DIV 32'h00000000 //23:16 (divide by 4)
`define SPI_CTL_CPOL 32'h00008000 //cuckoo(clock polar)
`define SPI_CTL_RD_ENDIAN 32'h00004000 //14
`define SPI_CTL_ASS 32'h00002000 //13
`define SPI_CTL_IE 32'h00001000 //12
`define SPI_CTL_LSB 32'h00000800 //11
`define SPI_CTL_TX_NEGEDGE 32'h00000400 //10
`define SPI_CTL_RX_NEGEDGE 32'h00000200 //9
`define SPI_CTL_GO 32'h00000100 //8
`define SPI_CTL_RES_1 32'h00000080 //7
`define SPI_CTL_CHAR_LEN 32'h00000040 //6:0(0x40=64bit)
`define SPI_ADDR_RXD0 5'h00
`define SPI_ADDR_RXD1 5'h04
`define SPI_ADDR_RXD2 5'h08
`define SPI_ADDR_RXD3 5'h0c
`define SPI_ADDR_TXD0 5'h00
`define SPI_ADDR_TXD1 5'h04
`define SPI_ADDR_TXD2 5'h08
`define SPI_ADDR_TXD3 5'h0c
`define SPI_ADDR_CTL 5'h10
`define SPI_ADDR_DIV 5'h14
`define SPI_ADDR_CS 5'h18
module spi_flash #(
parameter flash_addr_start = 32'h40000000,
parameter flash_addr_end = 32'h407fffff,
parameter spi_cs_num = 2
) (
input pclk,
input presetn,
input [ 31:0] paddr,
input psel,
input penable,
input pwrite,
input [ 31:0] pwdata,
input [ 3:0] pwstrb,
output pready,
output [ 31:0] prdata,
output pslverr,
input div4_i,
output spi_clk,
output [spi_cs_num-1:0] spi_cs,
output spi_mosi,
input spi_miso,
output spi_irq_out
);
wire pclk_spi;
wire presetn_spi;
wire [31:0] paddr_spi;
wire psel_spi;
wire penable_spi;
wire pwrite_spi;
wire [31:0] pwdata_spi;
wire [ 3:0] pwstrb_spi;
wire pready_spi;
wire [31:0] prdata_spi;
wire pslverr_spi;
wire clk;
wire rst_n;
wire is_flash;
reg [ 4:0] cmd_state;
reg [ 4:0] cmd_state_next;
reg [ 4:0] spi_state;
reg [ 4:0] spi_state_next;
reg [31:0] paddr_reg;
wire [31:0] paddr_in;
wire spi_fire;
wire [31:0] spi_tx_data0;
wire [31:0] spi_tx_data1;
wire [31:0] spi_ctl_data;
wire spi_irq;
wire [31:0] paddr_align = {paddr[31:2], 2'b00};
assign clk = pclk;
assign rst_n = presetn;
assign pclk_spi = pclk;
assign presetn_spi = presetn;
`define CMD_IDLE 5'h0
`define CMD_SPI_CSR 5'h1
`define CMD_WR_TXD0 5'h2
`define CMD_WR_TXD1 5'h3
`define CMD_WR_CTL 5'h4
`define CMD_WAIT_IRQ 5'h5
`define CMD_RD_RXD0 5'h6
`define SPI_IDLE 5'h0
`define SPI_ENABLE 5'h1
`define SPI_WAIT_READY 5'h2
always @(posedge clk) begin
if (!rst_n) paddr_reg <= 32'h0;
if (psel && penable) paddr_reg <= paddr_align;
end
assign paddr_in = paddr_align | paddr_reg;
assign is_flash = paddr_in >= flash_addr_start && paddr_in <= flash_addr_end;
assign psel_spi = spi_state == `SPI_WAIT_READY;
assign penable_spi = spi_state == `SPI_ENABLE || spi_state == `SPI_WAIT_READY;
assign spi_irq_out = cmd_state == `CMD_SPI_CSR ? spi_irq : 1'b0;
assign pwrite_spi = cmd_state == `CMD_SPI_CSR ? pwrite : cmd_state == `CMD_RD_RXD0 ? 1'b0 : 1'b1;
assign pwdata_spi = cmd_state == `CMD_SPI_CSR ? pwdata :
cmd_state == `CMD_WR_TXD0 ? spi_tx_data0 :
cmd_state == `CMD_WR_TXD1 ? spi_tx_data1 :
cmd_state == `CMD_WR_CTL ? spi_ctl_data : 32'h0;
assign pwstrb_spi = cmd_state == `CMD_SPI_CSR ? pwstrb : 4'hf;
assign prdata = prdata_spi;
assign paddr_spi = cmd_state == `CMD_SPI_CSR ? paddr_align[4:0]:
cmd_state == `CMD_WR_TXD0 ? `SPI_ADDR_TXD0 :
cmd_state == `CMD_WR_TXD1 ? `SPI_ADDR_TXD1 :
cmd_state == `CMD_WR_CTL ? `SPI_ADDR_CTL :
cmd_state == `CMD_RD_RXD0 ? `SPI_ADDR_RXD0 : 5'h0;
assign pready = cmd_state == `CMD_SPI_CSR && spi_fire || cmd_state == `CMD_RD_RXD0 && spi_fire;
assign pslverr = 1'b0;
assign spi_tx_data1 = 32'h03000000 | paddr_in[23:0]; //addr and readd cmd
assign spi_tx_data0 = 32'h00000000; //spi read 32bit data
assign spi_ctl_data = `SPI_CTL_SS | `SPI_CTL_DIV | `SPI_CTL_RD_ENDIAN | `SPI_CTL_ASS |
`SPI_CTL_IE | `SPI_CTL_TX_NEGEDGE | `SPI_CTL_GO | `SPI_CTL_CHAR_LEN;
//`SPI_CTL_IE | `SPI_CTL_GO | `SPI_CTL_CHAR_LEN;
always @(posedge clk) begin
if (!rst_n) cmd_state <= `CMD_IDLE;
else cmd_state <= cmd_state_next;
end
always @(cmd_state or psel or penable or spi_fire or spi_irq) begin
case (cmd_state)
`CMD_IDLE: begin
if (psel && penable) begin
if (is_flash && !pwrite) //read only!!!
cmd_state_next = `CMD_WR_TXD0;
else cmd_state_next = `CMD_SPI_CSR;
end else cmd_state_next = `CMD_IDLE;
end
`CMD_SPI_CSR: begin
if (spi_fire) cmd_state_next = `CMD_IDLE;
else cmd_state_next = `CMD_SPI_CSR;
end
`CMD_WR_TXD0: begin
if (spi_fire) cmd_state_next = `CMD_WR_TXD1;
else cmd_state_next = `CMD_WR_TXD0;
end
`CMD_WR_TXD1: begin
if (spi_fire) cmd_state_next = `CMD_WR_CTL;
else cmd_state_next = `CMD_WR_TXD1;
end
`CMD_WR_CTL: begin
if (spi_fire) cmd_state_next = `CMD_WAIT_IRQ;
else cmd_state_next = `CMD_WR_CTL;
end
`CMD_WAIT_IRQ: begin
if (spi_irq) cmd_state_next = `CMD_RD_RXD0;
else cmd_state_next = `CMD_WAIT_IRQ;
end
default: begin //`CMD_RD_RXD0
if (spi_fire) cmd_state_next = `CMD_IDLE;
else cmd_state_next = `CMD_RD_RXD0;
end
endcase
end
wire spi_apb_start;
assign spi_apb_start = cmd_state != `CMD_IDLE && cmd_state != `CMD_WAIT_IRQ;
always @(posedge clk) begin
if (!rst_n) spi_state <= 5'h0;
else spi_state <= spi_state_next;
end
always @(spi_state or spi_apb_start or pready_spi) begin
case (spi_state)
`SPI_IDLE: begin
if (spi_apb_start) spi_state_next = `SPI_ENABLE;
else spi_state_next = `SPI_IDLE;
end
`SPI_ENABLE: begin
spi_state_next = `SPI_WAIT_READY;
end
default: begin //SPI_WAIT_READY
if (pready_spi) spi_state_next = `SPI_IDLE;
else spi_state_next = `SPI_WAIT_READY;
end
endcase
end
assign spi_fire = spi_state == `SPI_WAIT_READY && pready_spi;
wire [7:0] ss_pad_o;
assign spi_cs = ss_pad_o[1:0];
spi_top u0_spi_top (
.div4_i (div4_i),
.PCLK (pclk),
.PRESETN(presetn),
.PADDR (paddr_spi[4:0]),
.PWDATA (pwdata_spi),
.PRDATA (prdata_spi),
.PSEL (psel_spi),
.PWRITE (pwrite_spi),
.PENABLE(penable_spi),
.PREADY (pready_spi),
.PSLVERR(pslverr_spi),
.ss_pad_o (ss_pad_o),
.sclk_pad_o(spi_clk),
.mosi_pad_o(spi_mosi),
.miso_pad_i(spi_miso),
.IRQ (spi_irq)
);
endmodule
-199
View File
@@ -1,199 +0,0 @@
`timescale 1ns/1ps
`include "spi_defines.v"
module spi_shift (clk, rst, latch, byte_sel, len, lsb, go,
pos_edge, neg_edge, rx_negedge, tx_negedge,
tip, last,
p_in, p_out, s_clk, s_in, s_out);
parameter Tp = 1;
input clk; // system clock
input rst; // reset
input [3:0] latch; // latch signal for storing the data in shift register
input [3:0] byte_sel; // byte select signals for storing the data in shift register
input [`SPI_CHAR_LEN_BITS-1:0] len; // data len in bits (minus one)
input lsb; // lbs first on the line
input go; // start stansfer
input pos_edge; // recognize posedge of sclk
input neg_edge; // recognize negedge of sclk
input rx_negedge; // s_in is sampled on negative edge
input tx_negedge; // s_out is driven on negative edge
output tip; // transfer in progress
output last; // last bit
input [31:0] p_in; // parallel in
output [`SPI_MAX_CHAR-1:0] p_out; // parallel out
input s_clk; // serial clock
input s_in; // serial in
output s_out; // serial out
reg s_out;
reg tip;
reg [`SPI_CHAR_LEN_BITS:0] cnt; // data bit count
reg [`SPI_MAX_CHAR-1:0] data; // shift register
wire [`SPI_CHAR_LEN_BITS:0] tx_bit_pos; // next bit position
wire [`SPI_CHAR_LEN_BITS:0] rx_bit_pos; // next bit position
wire rx_clk; // rx clock enable
wire tx_clk; // tx clock enable
wire [`SPI_CHAR_LEN_BITS:0] tx_bit_pos_tmp; // next bit position
assign p_out = data;
assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1};
assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} : cnt) :
(rx_negedge ? cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1});
assign last = !(|cnt);
assign rx_clk = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk);
assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last;
// Character bit counter
always @(posedge clk or posedge rst)
begin
if(rst)
cnt <= #Tp {`SPI_CHAR_LEN_BITS+1{1'b0}};
else
begin
if(tip)
cnt <= #Tp pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;
else
cnt <= #Tp !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};
end
end
// Transfer in progress
always @(posedge clk or posedge rst)
begin
if(rst)
tip <= #Tp 1'b0;
else if(go && ~tip)
tip <= #Tp 1'b1;
else if(tip && last && pos_edge)
tip <= #Tp 1'b0;
end
// Sending bits to the line
always @(posedge clk or posedge rst)
begin
if (rst)
s_out <= #Tp 1'b0;
else
s_out <= #Tp (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;
end
// Receiving bits from the line
always @(posedge clk or posedge rst)
begin
if (rst)
data <= #Tp {`SPI_MAX_CHAR{1'b0}};
`ifdef SPI_MAX_CHAR_128
else if (latch[0] && !tip)
begin
if (byte_sel[3])
data[31:24] <= #Tp p_in[31:24];
if (byte_sel[2])
data[23:16] <= #Tp p_in[23:16];
if (byte_sel[1])
data[15:8] <= #Tp p_in[15:8];
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
end
else if (latch[1] && !tip)
begin
if (byte_sel[3])
data[63:56] <= #Tp p_in[31:24];
if (byte_sel[2])
data[55:48] <= #Tp p_in[23:16];
if (byte_sel[1])
data[47:40] <= #Tp p_in[15:8];
if (byte_sel[0])
data[39:32] <= #Tp p_in[7:0];
end
else if (latch[2] && !tip)
begin
if (byte_sel[3])
data[95:88] <= #Tp p_in[31:24];
if (byte_sel[2])
data[87:80] <= #Tp p_in[23:16];
if (byte_sel[1])
data[79:72] <= #Tp p_in[15:8];
if (byte_sel[0])
data[71:64] <= #Tp p_in[7:0];
end
else if (latch[3] && !tip)
begin
if (byte_sel[3])
data[127:120] <= #Tp p_in[31:24];
if (byte_sel[2])
data[119:112] <= #Tp p_in[23:16];
if (byte_sel[1])
data[111:104] <= #Tp p_in[15:8];
if (byte_sel[0])
data[103:96] <= #Tp p_in[7:0];
end
`else
`ifdef SPI_MAX_CHAR_64
else if (latch[0] && !tip)
begin
if (byte_sel[3])
data[31:24] <= #Tp p_in[31:24];
if (byte_sel[2])
data[23:16] <= #Tp p_in[23:16];
if (byte_sel[1])
data[15:8] <= #Tp p_in[15:8];
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
end
else if (latch[1] && !tip)
begin
if (byte_sel[3])
data[63:56] <= #Tp p_in[31:24];
if (byte_sel[2])
data[55:48] <= #Tp p_in[23:16];
if (byte_sel[1])
data[47:40] <= #Tp p_in[15:8];
if (byte_sel[0])
data[39:32] <= #Tp p_in[7:0];
end
`else
else if (latch[0] && !tip)
begin
`ifdef SPI_MAX_CHAR_8
if (byte_sel[0])
data[`SPI_MAX_CHAR-1:0] <= #Tp p_in[`SPI_MAX_CHAR-1:0];
`endif
`ifdef SPI_MAX_CHAR_16
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
if (byte_sel[1])
data[`SPI_MAX_CHAR-1:8] <= #Tp p_in[`SPI_MAX_CHAR-1:8];
`endif
`ifdef SPI_MAX_CHAR_24
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
if (byte_sel[1])
data[15:8] <= #Tp p_in[15:8];
if (byte_sel[2])
data[`SPI_MAX_CHAR-1:16] <= #Tp p_in[`SPI_MAX_CHAR-1:16];
`endif
`ifdef SPI_MAX_CHAR_32
if (byte_sel[0])
data[7:0] <= #Tp p_in[7:0];
if (byte_sel[1])
data[15:8] <= #Tp p_in[15:8];
if (byte_sel[2])
data[23:16] <= #Tp p_in[23:16];
if (byte_sel[3])
data[`SPI_MAX_CHAR-1:24] <= #Tp p_in[`SPI_MAX_CHAR-1:24];
`endif
end
`endif
`endif
else
data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= #Tp rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
end
endmodule
-229
View File
@@ -1,229 +0,0 @@
`include "spi_defines.v"
module spi_top
(
div4_i,
// APB Signals
PCLK, PRESETN, PADDR, PWDATA, PRDATA, PSEL,
PWRITE, PENABLE, PREADY, PSLVERR,
// Interrupt
IRQ,
// SPI signals
ss_pad_o, sclk_pad_o, mosi_pad_o, miso_pad_i
);
parameter Tp = 1;
input div4_i;
input PCLK; // APB System Clock
input PRESETN; // APB Reset - Active low
input [4:0] PADDR; // APB Address
input [31:0] PWDATA; // Write data
output[31:0] PRDATA; // Read data
input PWRITE;
input PSEL;
input PENABLE;
output PREADY;
output PSLVERR;
output IRQ;
// SPI signals
output [`SPI_SS_NB-1:0] ss_pad_o; // slave select
output sclk_pad_o; // serial clock
output mosi_pad_o; // master out slave in
input miso_pad_i; // master in slave out
reg [31:0] PRDATA;
reg PREADY;
reg IRQ;
// Internal signals
//reg [`SPI_DIVIDER_LEN-1:0] divider; // Divider register
//reg [`SPI_SS_NB-1:0] ss; // Slave select register
reg [`SPI_CTRL_BIT_NB-1:0] ctrl; // Control and status register
reg [32-1:0] wb_dat; // wb data out
wire cpol; // clock polar(idel clock can be high(cpol==1) or low(cpol==0,default)
wire [`SPI_MAX_CHAR-1:0] rx; // Rx register
wire [`SPI_DIVIDER_LEN-1:0] divider; // Divider register
wire [`SPI_SS_NB-1:0] ss; // Slave select register
wire rx_negedge; // miso is sampled on negative edge
wire tx_negedge; // mosi is driven on negative edge
wire [`SPI_CHAR_LEN_BITS-1:0] char_len; // char len
wire go; // go
wire lsb; // lsb first on line
wire ie; // interrupt enable
wire ass; // automatic slave select
wire rd_endian; // apb read data endian
wire spi_divider_sel; // divider register select
wire spi_ctrl_sel; // ctrl register select
wire [3:0] spi_tx_sel; // tx_l register select
wire spi_ss_sel; // ss register select
wire tip; // transfer in progress
wire pos_edge; // recognize posedge of sclk
wire neg_edge; // recognize negedge of sclk
wire last_bit; // marks last character bit
// Address decoder
assign spi_divider_sel = PSEL & PENABLE & (PADDR[`SPI_OFS_BITS] == `SPI_DEVIDE);
assign spi_ctrl_sel = PSEL & PENABLE & (PADDR[`SPI_OFS_BITS] == `SPI_CTRL);
assign spi_tx_sel[0] = PSEL & PENABLE & (PADDR[`SPI_OFS_BITS] == `SPI_TX_0);
assign spi_tx_sel[1] = PSEL & PENABLE & (PADDR[`SPI_OFS_BITS] == `SPI_TX_1);
assign spi_tx_sel[2] = PSEL & PENABLE & (PADDR[`SPI_OFS_BITS] == `SPI_TX_2);
assign spi_tx_sel[3] = PSEL & PENABLE & (PADDR[`SPI_OFS_BITS] == `SPI_TX_3);
assign spi_ss_sel = PSEL & PENABLE & (PADDR[`SPI_OFS_BITS] == `SPI_SS);
// Read from registers
always @(PADDR or rx or ctrl or divider or ss)
begin
case (PADDR[`SPI_OFS_BITS])
`ifdef SPI_MAX_CHAR_128
`SPI_RX_0: wb_dat = rx[31:0];
`SPI_RX_1: wb_dat = rx[63:32];
`SPI_RX_2: wb_dat = rx[95:64];
`SPI_RX_3: wb_dat = {{128-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:96]};
`else
`ifdef SPI_MAX_CHAR_64
`SPI_RX_0: wb_dat = rx[31:0];
`SPI_RX_1: wb_dat = {{64-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:32]};
`SPI_RX_2: wb_dat = 32'b0;
`SPI_RX_3: wb_dat = 32'b0;
`else
`SPI_RX_0: wb_dat = {{32-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:0]};
`SPI_RX_1: wb_dat = 32'b0;
`SPI_RX_2: wb_dat = 32'b0;
`SPI_RX_3: wb_dat = 32'b0;
`endif
`endif
`SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl};
`SPI_DEVIDE: wb_dat = {{32-`SPI_DIVIDER_LEN{1'b0}}, divider};
`SPI_SS: wb_dat = {{32-`SPI_SS_NB{1'b0}}, ss};
default: wb_dat = 32'bx;
endcase
end
// Wb data out
always @(posedge PCLK or negedge PRESETN)
begin
if (PRESETN == 0)
PRDATA <= #Tp 32'b0;
//else
// PRDATA <= #Tp wb_dat;
else if(rd_endian) //cuckoo
PRDATA <= #Tp {wb_dat[7:0],wb_dat[15:8],wb_dat[23:16],wb_dat[31:24]};
else
PRDATA <= #Tp wb_dat;
end
// Wb acknowledge
always @(posedge PCLK or negedge PRESETN)
begin
if (PRESETN == 0)
PREADY <= #Tp 1'b0;
else
PREADY <= #Tp PSEL & PENABLE & ~PREADY;
end
// Wb error
assign PSLVERR = 1'b0;
// Interrupt
always @(posedge PCLK or negedge PRESETN)
begin
if (PRESETN == 0)
IRQ <= #Tp 1'b0;
else if (ie && tip && last_bit && pos_edge)
IRQ <= #Tp 1'b1;
else if (PREADY)
IRQ <= #Tp 1'b0;
end
/*
// Divider register
always @(posedge PCLK or negedge PRESETN)
begin
if (PRESETN == 0)
divider <= #Tp {`SPI_DIVIDER_LEN{1'b0}};
else if (spi_divider_sel && PWRITE && !tip)
begin
`ifdef SPI_DIVIDER_LEN_8
divider <= #Tp PWDATA[`SPI_DIVIDER_LEN-1:0];
`endif
`ifdef SPI_DIVIDER_LEN_16
divider[`SPI_DIVIDER_LEN-1:0] <= #Tp PWDATA[`SPI_DIVIDER_LEN-1:0];
`endif
`ifdef SPI_DIVIDER_LEN_24
divider[`SPI_DIVIDER_LEN-1:0] <= #Tp PWDATA[`SPI_DIVIDER_LEN-1:0];
`endif
`ifdef SPI_DIVIDER_LEN_32
divider[`SPI_DIVIDER_LEN-1:0] <= #Tp PWDATA[`SPI_DIVIDER_LEN-1:0];
`endif
end
end
*/
// Ctrl register
always @(posedge PCLK or negedge PRESETN)
begin
if (PRESETN == 0)
ctrl <= #Tp {`SPI_CTRL_BIT_NB{1'b0}};
else if(spi_ctrl_sel && PWRITE && !tip)
begin
ctrl[`SPI_CTRL_BIT_NB-1:0] <= #Tp PWDATA[`SPI_CTRL_BIT_NB-1:0];
end
else if(tip && last_bit && pos_edge)
ctrl[`SPI_CTRL_GO] <= #Tp 1'b0;
end
assign cpol = ctrl[`SPI_CTRL_CPOL];
assign ss = ctrl[`SPI_CTRL_SS];//cuckoo
assign divider = div4_i ? 8'd1 : ctrl[`SPI_CTRL_DIV]; //cuckoo
assign rd_endian = ctrl[`SPI_CTRL_RD_ENDIAN]; //cuckoo
assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE];
assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE];
assign go = ctrl[`SPI_CTRL_GO];
assign char_len = ctrl[`SPI_CTRL_CHAR_LEN];
assign lsb = ctrl[`SPI_CTRL_LSB];
assign ie = ctrl[`SPI_CTRL_IE];
assign ass = ctrl[`SPI_CTRL_ASS];
/*
// Slave select register
always @(posedge PCLK or negedge PRESETN)
begin
if (PRESETN == 0)
//ss <= #Tp {`SPI_SS_NB{1'b0}};
ss <= #Tp {`SPI_SS_NB{1'b0}} | `SPI_SS_NB'h1; //cuckoo default 1(chip select0)
else if(spi_ss_sel && PWRITE && !tip)
begin
`ifdef SPI_SS_NB_8
ss <= #Tp PWDATA[`SPI_SS_NB-1:0];
`endif
`ifdef SPI_SS_NB_16
ss[`SPI_SS_NB-1:0] <= #Tp PWDATA[`SPI_SS_NB-1:0];
`endif
`ifdef SPI_SS_NB_24
ss[`SPI_SS_NB-1:0] <= #Tp PWDATA[`SPI_SS_NB-1:0];
`endif
`ifdef SPI_SS_NB_32
ss[`SPI_SS_NB-1:0] <= #Tp PWDATA[`SPI_SS_NB-1:0];
`endif
end
end
*/
assign ss_pad_o = ~((ss & {`SPI_SS_NB{tip & ass}}) | (ss & {`SPI_SS_NB{!ass}}));
spi_clgen clgen (.clk_in(PCLK), .rst(!PRESETN), .go(go), .enable(tip), .last_clk(last_bit),
.divider(divider), .clk_out(sclk_pad_o), .pos_edge(pos_edge),
.neg_edge(neg_edge), .cpol(cpol));
spi_shift shift (.clk(PCLK), .rst(!PRESETN), .len(char_len[`SPI_CHAR_LEN_BITS-1:0]),
.latch(spi_tx_sel[3:0] & {4{PWRITE}}), .byte_sel(4'hF), .lsb(lsb),
.go(go), .pos_edge(pos_edge), .neg_edge(neg_edge),
.rx_negedge(rx_negedge), .tx_negedge(tx_negedge),
.tip(tip), .last(last_bit),
.p_in(PWDATA), .p_out(rx),
.s_clk(sclk_pad_o), .s_in(miso_pad_i), .s_out(mosi_pad_o));
endmodule
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-260
View File
@@ -1,260 +0,0 @@
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//
// Verilog Behavioral Model
// Version 1.2
//
// Copyright (c) 2013 Micron Inc.
//
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//
// This file and all files delivered herewith are Micron Confidential Information.
//
//
// Disclaimer of Warranty:
// -----------------------
// This software code and all associated documentation, comments
// or other information (collectively "Software") is provided
// "AS IS" without warranty of any kind. MICRON TECHNOLOGY, INC.
// ("MTI") EXPRESSLY DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO, NONINFRINGEMENT OF THIRD PARTY
// RIGHTS, AND ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
// FOR ANY PARTICULAR PURPOSE. MTI DOES NOT WARRANT THAT THE
// SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
// THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. FURTHERMORE,
// MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR THE
// RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
// ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT
// OF USE OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO
// EVENT SHALL MTI, ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE
// LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR
// SPECIAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
// OF PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION)
// ARISING OUT OF YOUR USE OF OR INABILITY TO USE THE SOFTWARE,
// EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
// Because some jurisdictions prohibit the exclusion or limitation
// of liability for consequential or incidental damages, the above
// limitation may not apply to you.
//
// Copyright 2013 Micron Technology, Inc. All rights reserved.
//
reg byte3 = 1;
`ifdef N25Q256A33E
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25Q256A31E
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25Q256A11E
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25Q256A13E
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25Q128A11E
// PLRS part1 detector
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25Q128A13E
// PLRS part1 detector
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25Q128A11B
// PLRS part1 detector
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25Q128A13B
// PLRS part1 detector
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
//`elsif N25Q064A11E
// // PLRS part1 detector
// PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
// PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
// PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
//
// // PLRS part2 detector
// PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
//
`elsif N25Q032A13E
// PLRS part1 detector
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25Q032A11E
// PLRS part1 detector
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25W032A13E
// PLRS part1 detector
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif N25W032A11E
// PLRS part1 detector
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD(S, C, byte3);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE(S, C, byte3);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif MT25QL512ABA1E0
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif MT25QL512ABA1F0
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif MT25QL512ABA8E0
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif MT25QL512ABA8F0
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif MT25QU512ABA1E0
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif MT25QU512ABA1F0
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif MT25QU512ABA8E0
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`elsif MT25QU512ABA8F0
// PLRS part1 detectors
PLRSpart1Detect #(.count(PLRS_1st_x4_byte3 - 1),.protocol("quad")) plrsQ3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x4_byte4 - 1),.protocol("quad")) plrsQ4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte3 - 1),.protocol("dual")) plrsD3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x2_byte4 - 1),.protocol("dual")) plrsD4b(S, C, prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte3 - 1),.protocol("extended")) plrsE3b(S, C, !prog.enable_4Byte_address);
PLRSpart1Detect #(.count(PLRS_1st_x1_byte4 - 1),.protocol("extended")) plrsE4b(S, C, prog.enable_4Byte_address);
// PLRS part2 detector
PLRSpart2Detect #(.count(PLRS_2nd - 1)) plrs2(S,C, busy);
`endif
-101
View File
@@ -1,101 +0,0 @@
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//
// Verilog Behavioral Model
// Version 1.2
//
// Copyright (c) 2013 Micron Inc.
//
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//
// This file and all files delivered herewith are Micron Confidential Information.
//
//
// Disclaimer of Warranty:
// -----------------------
// This software code and all associated documentation, comments
// or other information (collectively "Software") is provided
// "AS IS" without warranty of any kind. MICRON TECHNOLOGY, INC.
// ("MTI") EXPRESSLY DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO, NONINFRINGEMENT OF THIRD PARTY
// RIGHTS, AND ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
// FOR ANY PARTICULAR PURPOSE. MTI DOES NOT WARRANT THAT THE
// SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
// THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. FURTHERMORE,
// MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR THE
// RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
// ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT
// OF USE OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO
// EVENT SHALL MTI, ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE
// LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR
// SPECIAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
// OF PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION)
// ARISING OUT OF YOUR USE OF OR INABILITY TO USE THE SOFTWARE,
// EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
// Because some jurisdictions prohibit the exclusion or limitation
// of liability for consequential or incidental damages, the above
// limitation may not apply to you.
//
// Copyright 2013 Micron Technology, Inc. All rights reserved.
//
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- STACK DECODERS INSTANTIATIONS --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
`ifdef Stack1024Mb
`ifdef HOLD_pin
N25Qxxx #(.rdeasystacken(0),.rdeasystacken2(deviceStack)) N25Q_die0 (S,C,HOLD_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(1),.rdeasystacken2(deviceStack)) N25Q_die1 (S,C,HOLD_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(2),.rdeasystacken2(deviceStack)) N25Q_die2 (S,C,HOLD_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(3),.rdeasystacken2(deviceStack)) N25Q_die3 (S,C,HOLD_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
`else
N25Qxxx #(.rdeasystacken(0),.rdeasystacken2(deviceStack)) N25Q_die0 (S,C,RESET_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(1),.rdeasystacken2(deviceStack)) N25Q_die1 (S,C,RESET_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(2),.rdeasystacken2(deviceStack)) N25Q_die2 (S,C,RESET_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(3),.rdeasystacken2(deviceStack)) N25Q_die3 (S,C,RESET_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
`endif
`endif
`ifdef Stack512Mb
`ifdef HOLD_pin
N25Qxxx #(.rdeasystacken(0)) N25Q_die0 (S,C,HOLD_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(1)) N25Q_die1 (S,C,HOLD_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
`else
N25Qxxx #(.rdeasystacken(0)) N25Q_die0 (S,C,RESET_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(1)) N25Q_die1 (S,C,RESET_DQ3,DQ0,DQ1,Vcc,Vpp_W_DQ2);
`endif
`endif
`ifdef STACKED_MEDT_1G
`ifdef Feature_8
`ifdef HOLD_pin
N25Qxxx #(.rdeasystacken(0)) MT25Q_die0 (S, C, HOLD_DQ3, DQ0, DQ1, Vcc, Vpp_W_DQ2, RESET2);
N25Qxxx #(.rdeasystacken(1)) MT25Q_die1 (S, C, HOLD_DQ3, DQ0, DQ1, Vcc, Vpp_W_DQ2, RESET2);
`else
N25Qxxx #(.rdeasystacken(0)) MT25Q_die0 (S, C, RESET_DQ3, DQ0, DQ1, Vcc, Vpp_W_DQ2, RESET2);
N25Qxxx #(.rdeasystacken(1)) MT25Q_die1 (S, C, RESET_DQ3, DQ0, DQ1, Vcc, Vpp_W_DQ2, RESET2);
`endif
`else
`ifdef HOLD_pin
N25Qxxx #(.rdeasystacken(0)) MT25Q_die0 (S, C, HOLD_DQ3, DQ0, DQ1, Vcc, Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(1)) MT25Q_die1 (S, C, HOLD_DQ3, DQ0, DQ1, Vcc, Vpp_W_DQ2);
`else
N25Qxxx #(.rdeasystacken(0)) MT25Q_die0 (S, C, RESET_DQ3, DQ0, DQ1, Vcc, Vpp_W_DQ2);
N25Qxxx #(.rdeasystacken(1)) MT25Q_die1 (S, C, RESET_DQ3, DQ0, DQ1, Vcc, Vpp_W_DQ2);
`endif
`endif // Feature_8
`endif // STACKED_MEDT_1G
-266
View File
@@ -1,266 +0,0 @@
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//
// Verilog Behavioral Model
// Version 1.2
//
// Copyright (c) 2013 Micron Inc.
//
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//-MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON--MICRON-
//
// This file and all files delivered herewith are Micron Confidential Information.
//
//
// Disclaimer of Warranty:
// -----------------------
// This software code and all associated documentation, comments
// or other information (collectively "Software") is provided
// "AS IS" without warranty of any kind. MICRON TECHNOLOGY, INC.
// ("MTI") EXPRESSLY DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO, NONINFRINGEMENT OF THIRD PARTY
// RIGHTS, AND ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
// FOR ANY PARTICULAR PURPOSE. MTI DOES NOT WARRANT THAT THE
// SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
// THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. FURTHERMORE,
// MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR THE
// RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
// ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT
// OF USE OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO
// EVENT SHALL MTI, ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE
// LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR
// SPECIAL DAMAGES (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
// OF PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION)
// ARISING OUT OF YOUR USE OF OR INABILITY TO USE THE SOFTWARE,
// EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
// Because some jurisdictions prohibit the exclusion or limitation
// of liability for consequential or incidental damages, the above
// limitation may not apply to you.
//
// Copyright 2013 Micron Technology, Inc. All rights reserved.
//
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------------------------------
-----------------------------------------------------------
-- --
-- TIMING CONSTANTS --
-- --
-----------------------------------------------------------
-----------------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//--------------------------------------
// Max clock frequency (minimum period)
//--------------------------------------
parameter fC = 108; //max frequency in Mhz
parameter time TC = 9; //9ns=111.1Mhz
parameter fC_dtr = 66; // max frequency in Mhz in Double Transfer Rate
parameter TC_dtr = 15; // 15ns = 66.7Mhz
parameter fR = 54; //max frequency in Mhz during standard Read operation
parameter time TR = 18; //18ns=55.55Mhz
parameter fR_dtr = 27; // max frequency in Mhz during standard Read operation in Double Transfer Rate
parameter TR_dtr = 37; // 37ns = 27.03Mhz
//NB: in special read operations
// (fast read, dual output fast read, read SR,
// read lock register, read ID, read OTP)
// max clock frequency is fC
//---------------------------
// Input signals constraints
//---------------------------
// Clock signal constraints
parameter time tCH = 4;
parameter time tCL = 4;
parameter time tSLCH = 4;
//parameter time tDVCH = 2;
//parameter time tDVCH = 11.75;
parameter time tSHCH = 4;
parameter time tHLCH = 4;
parameter time tHHCH = 4;
parameter tCH_dtr = 6.75;
parameter tCL_dtr = 6.75;
// Chip select constraints
parameter time tCHSL = 4;
parameter time tCHSH = 4;
parameter time tSHSL = 20;
parameter time tVPPHSL = 200; //not implemented
parameter time tWHSL = 20;
parameter tSLCH_dtr = 6.75;
parameter tSHCH_dtr = 6.75;
parameter tCHSL_dtr = 6.75;
parameter tCHSH_dtr = 6.75;
parameter tCLSH = 3.375; // DTR only
// Data in constraints
parameter time tCHDX = 3;
// W signal constraints
parameter time tSHWL = 100;
// HOLD signal constraints
parameter time tCHHH = 4;
parameter time tCHHL = 4;
// RESET signal constraints
parameter time tRLRH = 50; // da sistemare
parameter time tSHRH = 2;
parameter time tRHSL_1 = 40; //during decoding
parameter time tRHSL_2 = 30000; //during program-erase operation (except subsector erase and WRSR)
parameter time tRHSL_3 = 500e6; //during subsector erase operation=tSSE
parameter time tRHSL_4 = 15e6; //during WRSR operation=tW
parameter time tRHSL_5 = 15e6; //during WRNVCR operation=tWNVCR
parameter time tRHSL_6 = 40; //when S is high in XIP mode and in standby mode
//-----------------------
// Output signal timings
//-----------------------
parameter time tSHQZ = 8;
parameter time tCLQV = 5; // 8 under 30 pF - 6 under 10 pF
parameter time tCLQX = 1; // min value
`ifdef MEDITERANEO
parameter time tHHQX = 8;
parameter time tHLQZ = 8;
`else
parameter time tHHQX = 8;
parameter time tHLQZ = 8;
`endif
parameter tCHQV = 6; // 6 under 30 pF - 5 under 10 pF - DTR only
parameter tCHQX = 1; // min value- DTR only
//--------------------
// Operation delays
//--------------------
`ifdef PowDown
parameter time tDP = 3e0;
parameter time tRDP = 30e0;
`endif
`ifdef N25Q064A13xx4My
parameter time tPP = 1e6;
parameter time tSSE = 60e6;
parameter time t32SSE = 220e6;
parameter time tSE = 460e6;
parameter time tBE = 45e9;
`else
parameter time tPP = 1e6;
parameter time tSSE = 3e9;
parameter time t32SSE = 3e9;
parameter time tSE = 700e6;
parameter time tBE = 240e9;
`endif
parameter time tDE = 80e6; // Needs to change
//aggiunta
`ifdef MEDITERANEO
parameter time tWNVCR = 200e3; //real value should be 200e9 (200ms), we use short value for simulation length
parameter time tWRASP = 200e6; //real value should be 200e9 (200ms), we use short value for simulation length
parameter time tW = 1.3e6;
`else
parameter time tWNVCR = 3e6;
parameter time tWRASP = 1;
parameter time tW = 1.3e3;
`endif
parameter time tWVCR = 40;
parameter time tWRVECR = 40;
parameter time tCFSR = 40;
parameter time tPOTP = 800000;
`ifdef byte_4
parameter time tWREAR = 40; // probable value
parameter time tEN4AD = 40; // probable value
parameter time tEX4AD = 40; // probable value
`endif
parameter tP_latency = 7e0;
parameter tSE_latency = 15e0;
parameter tSSE_latency = 15e0;
parameter write_PMR_delay = 5e5;
parameter progSusp_latencyTime = 25e3;
parameter eraseSusp_latencyTime = 25e3;
// Startup delays
//! parameter time tPUW = 10e6;
parameter time tVTR = 150e0;
parameter time tVTW = 150e0;
//---------------------------------
// Alias of timing constants above
//---------------------------------
parameter time program_delay = tPP;
parameter time program_OTP_delay = tPOTP;
parameter time program_latency = tP_latency;
parameter time write_SR_delay = tW;
parameter time clear_FSR_delay = tCFSR;
parameter time write_NVCR_delay = tWNVCR;
`ifdef MEDITERANEO
parameter time write_ASP_delay = tWRASP;
`endif
parameter time write_VCR_delay = tWVCR;
parameter time write_VECR_delay = tWRVECR;
`ifdef byte_4
parameter time write_EAR_delay = tWREAR;
parameter time enable4_address_delay = tEN4AD;
parameter time exit4_address_delay = tEX4AD;
`endif
parameter time erase_delay = tSE;
parameter time erase_latency = tSE_latency;
parameter time erase_bulk_delay = tBE;
parameter time erase_die_delay = tDE;
parameter time full_access_power_up_delay = tVTW;
parameter time read_access_power_up_delay = tVTR;
`ifdef SubSect
parameter time erase_ss_delay = tSSE;
parameter time erase_ss_latency = tSSE_latency;
`endif
`ifdef MEDT_SubSect32K
parameter time erase_ss32k_delay = t32SSE;
`endif
`ifdef PowDown
parameter time deep_power_down_delay = tDP;
parameter time release_power_down_delay = tRDP;
`endif
`ifdef MEDT_PPB
parameter time tPPBP = 1e5;
//parameter time tPPBP = 1;
parameter time tPPBE = 2e6;
parameter time write_PPB_delay = tPPBP;
parameter time erase_PPB_delay = tPPBE;
//parameter time write_PLB_delay = 1e5;
parameter time write_PLB_delay = 1;
`endif
parameter time write_PASSP_delay = 1e6;
`ifdef MEDITERANEO
parameter time tDVCH = 1.75;
`else
parameter time tDVCH = 1.75;
`endif
-16
View File
@@ -1,16 +0,0 @@
// ************************************
//
// User Data definition file :
//
// here are defined all parameters
// that the user can change
//
// ************************************
`define N25Q128A13E
`define FILENAME_mem "mem_Q128_bottom.vmf" // Memory File Name
`define FILENAME_sfdp "sfdp.vmf" // SFDP File Name
`define NVCR_DEFAULT_VALUE 'hFFFF
+189
View File
@@ -0,0 +1,189 @@
/*
* Ravenna - A full example SoC using PicoRV32 in ASIC
*
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
* Copyright (C) 2018,2019 Tim Edwards <tim@efabless.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
// -- Adaptable modifications are redistributed under compatible License --
//
// Copyright (c) 2023-2025 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
`ifndef NMI_GPIO_DEF_SV
`define NMI_GPIO_DEF_SV
// verilog_format: off
`define NMI_GPIO_NUM 8
`define NMI_GPIO_OE 8'h00 // rw
`define NMI_GPIO_CS 8'h04 // rw
`define NMI_GPIO_PU 8'h08 // rw
`define NMI_GPIO_PD 8'h0C // rw
`define NMI_GPIO_DO 8'h10 // rw
`define NMI_GPIO_DI 8'h14 // ro
// verilog_format: on
`endif
interface nmi_gpio_if #(
parameter int DATA_WIDTH = 32
) ();
logic [DATA_WIDTH-1:0] gpio_in;
logic [DATA_WIDTH-1:0] gpio_out;
logic [DATA_WIDTH-1:0] gpio_oe;
logic [DATA_WIDTH-1:0] gpio_cs;
logic [DATA_WIDTH-1:0] gpio_pu;
logic [DATA_WIDTH-1:0] gpio_pd;
modport dut(
input gpio_in,
output gpio_oe,
output gpio_cs,
output gpio_pu,
output gpio_pd,
output gpio_out
);
endinterface
module nmi_gpio (
// verilog_format: off
input logic clk_i,
input logic rst_n_i,
nmi_if.slave nmi,
nmi_gpio_if.dut gpio
// verilog_format: on
);
// nmi
logic s_nmi_wr_hdshk, s_nmi_rd_hdshk;
logic s_nmi_ready_d, s_nmi_ready_q;
logic s_nmi_rdata_en;
logic [31:0] s_nmi_rdata_d, s_nmi_rdata_q;
// register
logic s_gpio_oe_en;
logic [`NMI_GPIO_NUM-1:0] s_gpio_oe_d, s_gpio_oe_q;
logic s_gpio_cs_en;
logic [`NMI_GPIO_NUM-1:0] s_gpio_cs_d, s_gpio_cs_q;
logic s_gpio_pu_en;
logic [`NMI_GPIO_NUM-1:0] s_gpio_pu_d, s_gpio_pu_q;
logic s_gpio_pd_en;
logic [`NMI_GPIO_NUM-1:0] s_gpio_pd_d, s_gpio_pd_q;
logic s_gpio_do_en;
logic [`NMI_GPIO_NUM-1:0] s_gpio_do_d, s_gpio_do_q;
// HACK: because just wr/rd 8b GPIO
assign s_nmi_wr_hdshk = nmi.valid && (~s_nmi_ready_q) && nmi.wstrb[0];
assign s_nmi_rd_hdshk = nmi.valid && (~s_nmi_ready_q) && (~(|nmi.wstrb));
assign nmi.ready = s_nmi_ready_q;
assign nmi.rdata = s_nmi_rdata_q;
// gpio
assign gpio.gpio_oe = s_gpio_oe_q;
assign gpio.gpio_cs = s_gpio_cs_q; // 1: CMOS 0: SCHMI
assign gpio.gpio_pu = s_gpio_pu_q;
assign gpio.gpio_pd = s_gpio_pd_q;
assign gpio.gpio_out = s_gpio_do_q;
// register
assign s_gpio_oe_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_GPIO_OE;
assign s_gpio_oe_d = nmi.wdata[`NMI_GPIO_NUM-1:0];
dffer #(`NMI_GPIO_NUM) u_gpio_oe_dffer (
clk_i,
rst_n_i,
s_gpio_oe_en,
s_gpio_oe_d,
s_gpio_oe_q
);
assign s_gpio_cs_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_GPIO_CS;
assign s_gpio_cs_d = nmi.wdata[`NMI_GPIO_NUM-1:0];
dffer #(`NMI_GPIO_NUM) u_gpio_cs_dffer (
clk_i,
rst_n_i,
s_gpio_cs_en,
s_gpio_cs_d,
s_gpio_cs_q
);
assign s_gpio_pu_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_GPIO_PU;
assign s_gpio_pu_d = nmi.wdata[`NMI_GPIO_NUM-1:0];
dffer #(`NMI_GPIO_NUM) u_gpio_pu_dffer (
clk_i,
rst_n_i,
s_gpio_pu_en,
s_gpio_pu_d,
s_gpio_pu_q
);
assign s_gpio_pd_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_GPIO_PD;
assign s_gpio_pd_d = nmi.wdata[`NMI_GPIO_NUM-1:0];
dffer #(`NMI_GPIO_NUM) u_gpio_pd_dffer (
clk_i,
rst_n_i,
s_gpio_pd_en,
s_gpio_pd_d,
s_gpio_pd_q
);
assign s_gpio_do_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_GPIO_DO;
assign s_gpio_do_d = nmi.wdata[`NMI_GPIO_NUM-1:0];
dffer #(`NMI_GPIO_NUM) u_gpio_do_dffer (
clk_i,
rst_n_i,
s_gpio_do_en,
s_gpio_do_d,
s_gpio_do_q
);
// nmi resp
assign s_nmi_ready_d = nmi.valid && (~s_nmi_ready_q);
dffr #(1) u_nmi_ready_dffr (
clk_i,
rst_n_i,
s_nmi_ready_d,
s_nmi_ready_q
);
assign s_nmi_rdata_en = s_nmi_rd_hdshk;
always_comb begin
s_nmi_rdata_d = s_nmi_rdata_q;
unique case (nmi.addr[7:0])
`NMI_GPIO_OE: s_nmi_rdata_d = {{(32 - `NMI_GPIO_NUM) {1'b0}}, s_gpio_oe_q};
`NMI_GPIO_CS: s_nmi_rdata_d = {{(32 - `NMI_GPIO_NUM) {1'b0}}, s_gpio_cs_q};
`NMI_GPIO_PU: s_nmi_rdata_d = {{(32 - `NMI_GPIO_NUM) {1'b0}}, s_gpio_pu_q};
`NMI_GPIO_PD: s_nmi_rdata_d = {{(32 - `NMI_GPIO_NUM) {1'b0}}, s_gpio_pd_q};
`NMI_GPIO_DO: s_nmi_rdata_d = {{(32 - `NMI_GPIO_NUM) {1'b0}}, s_gpio_do_q};
`NMI_GPIO_DI: s_nmi_rdata_d = {{(32 - `NMI_GPIO_NUM) {1'b0}}, gpio.gpio_in};
default: s_nmi_rdata_d = s_nmi_rdata_q;
endcase
end
dffer #(32) u_nmi_rdata_dffer (
clk_i,
rst_n_i,
s_nmi_rdata_en,
s_nmi_rdata_d,
s_nmi_rdata_q
);
endmodule
+4 -13
View File
@@ -26,8 +26,7 @@ module nmi2apb (
apb4_pure_if.master rtc,
apb4_pure_if.master wdg,
apb4_pure_if.master crc,
apb4_pure_if.master tmr,
apb4_pure_if.master spfs
apb4_pure_if.master tmr
// verilog_format: on
);
@@ -51,7 +50,6 @@ module nmi2apb (
assign wdg.paddr = nmi.addr;
assign crc.paddr = nmi.addr;
assign tmr.paddr = nmi.addr;
assign spfs.paddr = nmi.addr;
assign archinfo.pprot = '0;
assign rng.pprot = '0;
@@ -62,7 +60,6 @@ module nmi2apb (
assign wdg.pprot = '0;
assign crc.pprot = '0;
assign tmr.pprot = '0;
assign spfs.pprot = '0;
assign archinfo.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_ARCHINFO_START);
assign rng.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_RNG_START);
@@ -73,7 +70,6 @@ module nmi2apb (
assign wdg.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_WDG_START);
assign crc.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_CRC_START);
assign tmr.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_TMR_START);
assign spfs.psel = s_xfer_valid && (nmi.addr[31:28] == `FLASH_START);
assign archinfo.penable = s_fsm_q == FSM_ENAB;
assign rng.penable = s_fsm_q == FSM_ENAB;
@@ -84,7 +80,6 @@ module nmi2apb (
assign wdg.penable = s_fsm_q == FSM_ENAB;
assign crc.penable = s_fsm_q == FSM_ENAB;
assign tmr.penable = s_fsm_q == FSM_ENAB;
assign spfs.penable = s_fsm_q == FSM_ENAB;
assign archinfo.pwrite = |nmi.wstrb;
assign rng.pwrite = |nmi.wstrb;
@@ -95,7 +90,6 @@ module nmi2apb (
assign wdg.pwrite = |nmi.wstrb;
assign crc.pwrite = |nmi.wstrb;
assign tmr.pwrite = |nmi.wstrb;
assign spfs.pwrite = |nmi.wstrb;
assign archinfo.pwdata = nmi.wdata;
assign rng.pwdata = nmi.wdata;
@@ -106,7 +100,6 @@ module nmi2apb (
assign wdg.pwdata = nmi.wdata;
assign crc.pwdata = nmi.wdata;
assign tmr.pwdata = nmi.wdata;
assign spfs.pwdata = nmi.wdata;
assign archinfo.pstrb = nmi.wstrb;
assign rng.pstrb = nmi.wstrb;
@@ -117,7 +110,6 @@ module nmi2apb (
assign wdg.pstrb = nmi.wstrb;
assign crc.pstrb = nmi.wstrb;
assign tmr.pstrb = nmi.wstrb;
assign spfs.pstrb = nmi.wstrb;
`ifdef IP_MDD
assign user_ip.paddr = nmi.addr;
@@ -168,11 +160,11 @@ module nmi2apb (
({32{rtc.psel}} & rtc.prdata) |
({32{wdg.psel}} & wdg.prdata) |
({32{crc.psel}} & crc.prdata) |
({32{tmr.psel}} & tmr.prdata) |
`ifdef IP_MDD
({32{user_ip.psel}} & user_ip.prdata) |
`endif
({32{spfs.psel}} & spfs.prdata);
({32{tmr.psel}} & tmr.prdata);
assign s_xfer_ready = (archinfo.psel & archinfo.pready) |
(rng.psel & rng.pready) |
@@ -182,11 +174,10 @@ module nmi2apb (
(rtc.psel & rtc.pready) |
(wdg.psel & wdg.pready) |
(crc.psel & crc.pready) |
(tmr.psel & tmr.pready) |
`ifdef IP_MDD
(user_ip.psel & user_ip.pready) |
`endif
(spfs.psel & spfs.pready);
(tmr.psel & tmr.pready);
// verilog_format: on
endmodule
+9 -5
View File
@@ -57,11 +57,14 @@ module nmi_psram (
// verilog_format: on
);
localparam FSM_IDLE = 0;
localparam FSM_WE_ST = 1;
localparam FSM_WE = 2;
localparam FSM_RD_ST = 3;
localparam FSM_RD = 4;
// verilog_format: off
localparam FSM_IDLE = 6'd0;
localparam FSM_WE_ST = 6'd1;
localparam FSM_WE = 6'd2;
localparam FSM_RD_ST = 6'd3;
localparam FSM_RD = 6'd4;
// verilog_format: on
// reg
logic [ 4:0] r_cfg_wait;
logic [ 2:0] r_cfg_chd;
@@ -147,6 +150,7 @@ module nmi_psram (
r_mem_wdata <= '0;
end else begin
if (s_mem_sel) begin
/* verilator lint_off CASEINCOMPLETE */
case (r_fsm_state)
FSM_IDLE: begin
if (s_mem_valid_re && (|nmi.wstrb)) begin
+20 -17
View File
@@ -38,21 +38,23 @@ module psram_core (
// 6.94 * 50000 = 347us / 2 = 174us > 150us
`define BOOT_COUNTER 18'd50_000
localparam FSM_INIT = 0;
localparam FSM_RSTEN = 1;
localparam FSM_RSTEN2RST = 2;
localparam FSM_RST = 3;
localparam FSM_RST2QE = 4;
localparam FSM_QE = 5;
localparam FSM_QE2IDLE = 6;
localparam FSM_IDLE = 7;
localparam FSM_SEND = 8;
localparam FSM_SEND_QPI = 9;
localparam FSM_RD_PRE_QPI = 10;
localparam FSM_RD_QPI = 11;
localparam FSM_WR_QPI = 12;
localparam FSM_RD2IDLE = 13;
localparam FSM_WR2IDLE = 14;
// verilog_format: off
localparam FSM_INIT = 5'd0;
localparam FSM_RSTEN = 5'd1;
localparam FSM_RSTEN2RST = 5'd2;
localparam FSM_RST = 5'd3;
localparam FSM_RST2QE = 5'd4;
localparam FSM_QE = 5'd5;
localparam FSM_QE2IDLE = 5'd6;
localparam FSM_IDLE = 5'd7;
localparam FSM_SEND = 5'd8;
localparam FSM_SEND_QPI = 5'd9;
localparam FSM_RD_PRE_QPI = 5'd10;
localparam FSM_RD_QPI = 5'd11;
localparam FSM_WR_QPI = 5'd12;
localparam FSM_RD2IDLE = 5'd13;
localparam FSM_WR2IDLE = 5'd14;
// verilog_format: on
logic [ 4:0] r_fsm_state;
logic [ 4:0] r_fsm_state_tgt;
@@ -130,6 +132,7 @@ module psram_core (
psram_ce_o <= 1'b1;
end else begin
mem_ready_o <= 1'b0;
/* verilator lint_off CASEINCOMPLETE */
case (r_fsm_state)
FSM_INIT: begin
if (r_boot_cnt == 18'd0) r_fsm_state <= FSM_RSTEN;
@@ -200,7 +203,7 @@ module psram_core (
psram_ce_o <= 1'b1;
end else if (r_wr_st) begin
r_xfer_ca <= {8'h38, mem_addr_i[23:0]};
r_xfer_ca_bit_cnt <= 32;
r_xfer_ca_bit_cnt <= 8'd32;
r_fsm_state <= FSM_SEND_QPI;
r_fsm_state_tgt <= FSM_WR_QPI;
r_xfer_data_bit_cnt <= 8'd0;
@@ -208,7 +211,7 @@ module psram_core (
psram_ce_o <= 1'b0;
end else if (r_rd_st) begin
r_xfer_ca <= {8'hEB, mem_addr_i[23:0]};
r_xfer_ca_bit_cnt <= 32;
r_xfer_ca_bit_cnt <= 8'd32;
r_fsm_state <= FSM_SEND_QPI;
r_fsm_state_tgt <= FSM_RD_PRE_QPI;
r_rd_wait_cnt <= 4'd12; // wait 6 cycle afer cmd+addr accrondig to TRM
+217 -50
View File
@@ -21,6 +21,11 @@ module nmi_qspi (
qspi_if.dut qspi
// verilog_format: on
);
localparam FSM_IDLE = 6'd0;
localparam FSM_WE_ST = 6'd1;
localparam FSM_WE = 6'd2;
localparam FSM_RD_ST = 6'd3;
localparam FSM_RD = 6'd4;
logic s_nmi_wr_hdshk, s_nmi_rd_hdshk;
logic s_nmi_ready_d, s_nmi_ready_q;
@@ -78,12 +83,15 @@ module nmi_qspi (
logic s_qspi_start_d, s_qspi_start_q;
logic s_qspi_status_en;
logic [20:0] s_qspi_status_d, s_qspi_status_q;
// mm mode
logic s_qspi_mmmode_en;
logic s_qspi_mmmode_d, s_qspi_mmmode_q;
// common
logic s_xfer_start, s_xfer_done;
logic s_tx_fifo_stall_d, s_tx_fifo_stall_q;
logic s_rx_fifo_stall_d, s_rx_fifo_stall_q;
// tx fifo
logic s_tx_push_valid; // NOTE: push ready?
logic s_tx_push_valid, s_tx_push_ready;
logic s_tx_pop_valid, s_tx_pop_ready;
logic s_tx_empty, s_tx_full;
logic [31:0] s_tx_push_data, s_tx_pop_data;
@@ -93,7 +101,18 @@ module nmi_qspi (
logic s_rx_pop_valid, s_rx_pop_ready;
logic s_rx_empty, s_rx_full;
logic [31:0] s_rx_push_data, s_rx_pop_data;
logic [6:0] s_rx_elem_num;
logic [ 6:0] s_rx_elem_num;
// memory-mapped
logic r_mm_rd_st;
logic r_mm_wr_st;
logic [ 7:0] r_mm_xfer_byte_cnt;
logic [ 5:0] r_mm_fsm_state;
logic [23:0] r_mm_mem_addr;
logic [31:0] r_mm_mem_wdata;
logic [ 1:0] s_mm_disp_addr_ofst;
logic [ 7:0] s_mm_disp_byte_cnt;
logic [31:0] s_mm_disp_wdata;
logic s_mem_valid_re;
assign s_nmi_wr_hdshk = nmi.valid && (~s_nmi_ready_q) && (|nmi.wstrb);
@@ -358,7 +377,8 @@ module nmi_qspi (
end
end
assign s_tx_pop_ready = ~s_tx_empty;
assign s_tx_push_ready = ~s_tx_full;
assign s_tx_pop_ready = ~s_tx_empty;
fifo #(
.DATA_WIDTH (32),
.BUFFER_DEPTH(256)
@@ -423,6 +443,17 @@ module nmi_qspi (
);
assign s_qspi_mmmode_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NATV_QSPI_MMMODE;
assign s_qspi_mmmode_d = nmi.wdata[0];
dffer #(1) u_qspi_mmmode_dffer (
clk_i,
rst_n_i,
s_qspi_mmmode_en,
s_qspi_mmmode_d,
s_qspi_mmmode_q
);
always_comb begin
s_tx_fifo_stall_d = s_tx_fifo_stall_q;
if (~s_tx_fifo_stall_q && s_tx_elem_num[7:0] > s_qspi_txupbound_q) begin
@@ -456,7 +487,7 @@ module nmi_qspi (
// rd
assign s_nmi_ready_d = nmi.valid && (~s_nmi_ready_q);
assign s_nmi_ready_d = ~s_qspi_mmmode_q ? s_rx_pop_ready : (nmi.valid && (~s_nmi_ready_q));
dffr #(1) u_nmi_ready_dffr (
clk_i,
rst_n_i,
@@ -468,36 +499,43 @@ module nmi_qspi (
always_comb begin
s_rx_pop_valid = '0;
s_nmi_rdata_d = s_nmi_rdata_q;
unique case (nmi.addr[7:0])
`NATV_QSPI_MODE: s_nmi_rdata_d = {31'd0, s_qspi_mode_q};
`NATV_QSPI_NSS: s_nmi_rdata_d = {28'd0, s_qspi_nss_q};
`NATV_QSPI_CLKDIV: s_nmi_rdata_d = {24'd0, s_qspi_clkdiv_q};
`NATV_QSPI_RDWR: s_nmi_rdata_d = {31'd0, s_qspi_rdwr_q};
`NATV_QSPI_REVDAT: s_nmi_rdata_d = {31'd0, s_qspi_revdat_q};
`NATV_QSPI_TXUPBOUND: s_nmi_rdata_d = {24'd0, s_qspi_txupbound_q};
`NATV_QSPI_TXLOWBOUND: s_nmi_rdata_d = {24'd0, s_qspi_txlowbound_q};
`NATV_QSPI_RXUPBOUND: s_nmi_rdata_d = {26'd0, s_qspi_rxupbound_q};
`NATV_QSPI_RXLOWBOUND: s_nmi_rdata_d = {26'd0, s_qspi_rxlowbound_q};
`NATV_QSPI_CMDTYP: s_nmi_rdata_d = {30'd0, s_qspi_cmdtyp_q};
`NATV_QSPI_CMDLEN: s_nmi_rdata_d = {29'd0, s_qspi_cmdlen_q};
`NATV_QSPI_CMDDAT: s_nmi_rdata_d = s_qspi_cmddat_q;
`NATV_QSPI_ADRTYP: s_nmi_rdata_d = {30'd0, s_qspi_adrtyp_q};
`NATV_QSPI_ADRLEN: s_nmi_rdata_d = {29'd0, s_qspi_adrlen_q};
`NATV_QSPI_ADRDAT: s_nmi_rdata_d = s_qspi_adrdat_q;
`NATV_QSPI_DUMLEN: s_nmi_rdata_d = {24'd0, s_qspi_dumlen_q};
`NATV_QSPI_DATTYP: s_nmi_rdata_d = {30'd0, s_qspi_dattyp_q};
`NATV_QSPI_DATLEN: s_nmi_rdata_d = {24'd0, s_qspi_datlen_q};
`NATV_QSPI_DATBIT: s_nmi_rdata_d = {29'd0, s_qspi_datbit_q};
`NATV_QSPI_RXDATA: begin
if (s_nmi_rd_hdshk) begin
s_rx_pop_valid = 1'b1;
if (s_rx_pop_ready) s_nmi_rdata_d = s_rx_pop_data;
else s_nmi_rdata_d = '0;
if (~s_qspi_mmmode_q) begin
s_rx_pop_valid = 1'b1;
if (s_rx_pop_ready) s_nmi_rdata_d = s_rx_pop_data;
end else begin
unique case (nmi.addr[7:0])
`NATV_QSPI_MODE: s_nmi_rdata_d = {31'd0, s_qspi_mode_q};
`NATV_QSPI_NSS: s_nmi_rdata_d = {28'd0, s_qspi_nss_q};
`NATV_QSPI_CLKDIV: s_nmi_rdata_d = {24'd0, s_qspi_clkdiv_q};
`NATV_QSPI_RDWR: s_nmi_rdata_d = {31'd0, s_qspi_rdwr_q};
`NATV_QSPI_REVDAT: s_nmi_rdata_d = {31'd0, s_qspi_revdat_q};
`NATV_QSPI_TXUPBOUND: s_nmi_rdata_d = {24'd0, s_qspi_txupbound_q};
`NATV_QSPI_TXLOWBOUND: s_nmi_rdata_d = {24'd0, s_qspi_txlowbound_q};
`NATV_QSPI_RXUPBOUND: s_nmi_rdata_d = {26'd0, s_qspi_rxupbound_q};
`NATV_QSPI_RXLOWBOUND: s_nmi_rdata_d = {26'd0, s_qspi_rxlowbound_q};
`NATV_QSPI_CMDTYP: s_nmi_rdata_d = {30'd0, s_qspi_cmdtyp_q};
`NATV_QSPI_CMDLEN: s_nmi_rdata_d = {29'd0, s_qspi_cmdlen_q};
`NATV_QSPI_CMDDAT: s_nmi_rdata_d = s_qspi_cmddat_q;
`NATV_QSPI_ADRTYP: s_nmi_rdata_d = {30'd0, s_qspi_adrtyp_q};
`NATV_QSPI_ADRLEN: s_nmi_rdata_d = {29'd0, s_qspi_adrlen_q};
`NATV_QSPI_ADRDAT: s_nmi_rdata_d = s_qspi_adrdat_q;
`NATV_QSPI_DUMLEN: s_nmi_rdata_d = {24'd0, s_qspi_dumlen_q};
`NATV_QSPI_DATTYP: s_nmi_rdata_d = {30'd0, s_qspi_dattyp_q};
`NATV_QSPI_DATLEN: s_nmi_rdata_d = {24'd0, s_qspi_datlen_q};
`NATV_QSPI_DATBIT: s_nmi_rdata_d = {29'd0, s_qspi_datbit_q};
`NATV_QSPI_RXDATA: begin
if (s_nmi_rd_hdshk) begin
s_rx_pop_valid = 1'b1;
if (s_rx_pop_ready) s_nmi_rdata_d = s_rx_pop_data;
else s_nmi_rdata_d = '0;
end
end
end
`NATV_QSPI_STATUS: s_nmi_rdata_d = {11'd0, s_qspi_status_q};
default: s_nmi_rdata_d = s_nmi_rdata_q;
endcase
`NATV_QSPI_STATUS: s_nmi_rdata_d = {11'd0, s_qspi_status_q};
`NATV_QSPI_MMMODE: s_nmi_rdata_d = {31'd0, s_qspi_mmmode_q};
default: s_nmi_rdata_d = s_nmi_rdata_q;
endcase
end
end
dffer #(32) u_nmi_rdata_dffer (
clk_i,
@@ -511,33 +549,162 @@ module nmi_qspi (
qspi_core u_qspi_core (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.mode_i (s_qspi_mode_q),
.nss_i (s_qspi_nss_q),
.clkdiv_i (s_qspi_clkdiv_q),
.rdwr_i (s_qspi_rdwr_q),
.revdat_i (s_qspi_revdat_q),
.cmdtyp_i (s_qspi_cmdtyp_q),
.cmdlen_i (s_qspi_cmdlen_q),
.cmddat_i (s_qspi_cmddat_q),
.adrtyp_i (s_qspi_adrtyp_q),
.adrlen_i (s_qspi_adrlen_q),
.adrdat_i (s_qspi_adrdat_q),
.dumlen_i (s_qspi_dumlen_q),
.dattyp_i (s_qspi_dattyp_q),
.datlen_i (s_qspi_datlen_q),
.datbit_i (s_qspi_datbit_q),
.hlvlen_i (s_qspi_hlvlen_q),
.mode_i (~s_qspi_mmmode_q ? 1'b0 : s_qspi_mode_q),
.nss_i (~s_qspi_mmmode_q ? 4'd1 : s_qspi_nss_q),
.clkdiv_i (~s_qspi_mmmode_q ? 8'd0 : s_qspi_clkdiv_q),
.rdwr_i (~s_qspi_mmmode_q ? 1'b1 : s_qspi_rdwr_q),
.revdat_i (~s_qspi_mmmode_q ? 1'b0 : s_qspi_revdat_q),
.cmdtyp_i (~s_qspi_mmmode_q ? 2'd1 : s_qspi_cmdtyp_q),
.cmdlen_i (~s_qspi_mmmode_q ? 3'd1 : s_qspi_cmdlen_q),
.cmddat_i (~s_qspi_mmmode_q ? 32'hEB000000 : s_qspi_cmddat_q),
.adrtyp_i (~s_qspi_mmmode_q ? 2'd3 : s_qspi_adrtyp_q),
.adrlen_i (~s_qspi_mmmode_q ? 3'd4 : s_qspi_adrlen_q),
.adrdat_i (~s_qspi_mmmode_q ? {r_mm_mem_addr, 8'hF0} : s_qspi_adrdat_q),
.dumlen_i (~s_qspi_mmmode_q ? 8'd4 : s_qspi_dumlen_q),
.dattyp_i (~s_qspi_mmmode_q ? 2'd3 : s_qspi_dattyp_q),
.datlen_i (~s_qspi_mmmode_q ? 8'd1 : s_qspi_datlen_q),
.datbit_i (~s_qspi_mmmode_q ? 3'd4 : s_qspi_datbit_q),
.hlvlen_i (~s_qspi_mmmode_q ? 8'd2 : s_qspi_hlvlen_q),
.tx_data_req_o (s_tx_pop_valid),
.tx_data_rdy_i (s_tx_pop_ready),
.tx_data_i (s_tx_pop_data),
.rx_data_req_o (s_rx_push_valid),
.rx_data_rdy_i (s_rx_push_ready),
.rx_data_o (s_rx_push_data),
.start_i (s_xfer_start),
.start_i (~s_qspi_mmmode_q ? r_mm_rd_st : s_xfer_start),
.done_o (s_xfer_done),
.tx_elem_num_i (s_tx_elem_num[7:0]),
.dma_xfer_done_i(dma_xfer_done_i),
.qspi (qspi)
);
// memory-mapped mode
edge_det_sync_re #(1) u_mem_valid_edge_det_sync_re (
clk_i,
rst_n_i,
nmi.valid,
s_mem_valid_re
);
always_ff @(posedge clk_i, negedge rst_n_i) begin
if (~rst_n_i) begin
r_mm_rd_st <= '0;
r_mm_wr_st <= '0;
r_mm_xfer_byte_cnt <= '0;
r_mm_fsm_state <= FSM_IDLE;
r_mm_mem_addr <= '0;
r_mm_mem_wdata <= '0;
end else begin
if (nmi.addr[31:28] == `FLASH_START) begin
unique case (r_mm_fsm_state)
FSM_IDLE: begin
if (s_mem_valid_re) begin
if (|nmi.wstrb) begin
r_mm_fsm_state <= FSM_WE_ST;
r_mm_xfer_byte_cnt <= s_mm_disp_byte_cnt;
r_mm_mem_addr <= nmi.addr[23:0] + {22'd0, s_mm_disp_addr_ofst};
r_mm_mem_wdata <= s_mm_disp_wdata;
end else begin
r_mm_fsm_state <= FSM_RD_ST;
r_mm_xfer_byte_cnt <= 8'd4;
r_mm_mem_addr <= nmi.addr[23:0];
r_mm_mem_wdata <= nmi.wdata; // NOTE: no used
end
end
end
FSM_WE_ST: begin
if (s_tx_push_ready) begin
r_mm_wr_st <= 1'b1;
r_mm_fsm_state <= FSM_WE;
end
end
FSM_WE: begin
r_mm_wr_st <= 1'b0;
if (s_xfer_done) r_mm_fsm_state <= FSM_IDLE;
end
FSM_RD_ST: begin
if (1'b1) begin
r_mm_rd_st <= 1'b1;
r_mm_fsm_state <= FSM_RD;
end
end
FSM_RD: begin
r_mm_rd_st <= 1'b0;
if (s_rx_pop_ready) r_mm_fsm_state <= FSM_IDLE;
end
default: begin
r_mm_rd_st <= '0;
r_mm_wr_st <= '0;
r_mm_xfer_byte_cnt <= '0;
r_mm_fsm_state <= FSM_IDLE;
r_mm_mem_addr <= '0;
r_mm_mem_wdata <= '0;
end
endcase
end
end
end
xfer_dispatcher u_xfer_dispatcher (
.wstrb_i (nmi.wstrb),
.wdata_i (nmi.wdata),
.addr_ofst_o (s_mm_disp_addr_ofst),
.xfer_byte_cnt_o(s_mm_disp_byte_cnt),
.wdata_o (s_mm_disp_wdata)
);
endmodule
module xfer_dispatcher (
input logic [ 3:0] wstrb_i,
input logic [31:0] wdata_i,
output logic [ 1:0] addr_ofst_o,
output logic [ 7:0] xfer_byte_cnt_o,
output logic [31:0] wdata_o
);
always_comb begin
wdata_o = wdata_i;
case (wstrb_i)
4'b0001: begin
addr_ofst_o = 2'd0;
xfer_byte_cnt_o = 8'd1;
wdata_o[7:0] = wdata_i[7:0];
end
4'b0010: begin
addr_ofst_o = 2'd1;
xfer_byte_cnt_o = 8'd1;
wdata_o[7:0] = wdata_i[15:8];
end
4'b0100: begin
addr_ofst_o = 2'd2;
xfer_byte_cnt_o = 8'd1;
wdata_o[7:0] = wdata_i[23:16];
end
4'b1000: begin
addr_ofst_o = 2'd3;
xfer_byte_cnt_o = 8'd1;
wdata_o[7:0] = wdata_i[31:24];
end
4'b0011: begin
addr_ofst_o = 2'd0;
xfer_byte_cnt_o = 8'd2;
wdata_o[15:0] = wdata_i[15:0];
end
4'b1100: begin
addr_ofst_o = 2'd2;
xfer_byte_cnt_o = 8'd2;
wdata_o[15:0] = wdata_i[31:16];
end
4'b1111: begin
addr_ofst_o = 2'd0;
xfer_byte_cnt_o = 8'd4;
wdata_o[31:0] = wdata_i[31:0];
end
default: begin
addr_ofst_o = 2'd0;
xfer_byte_cnt_o = 8'd4;
wdata_o = wdata_i[31:0];
end
endcase
end
endmodule
+2 -2
View File
@@ -381,8 +381,8 @@ module qspi_core (
3'd1: rx_data_o = {24'd0, s_xfer_data_q[7:0]};
3'd2: rx_data_o = {16'd0, s_xfer_data_q[15:0]};
3'd3: rx_data_o = {8'd0, s_xfer_data_q[23:0]};
3'd4: rx_data_o = s_xfer_data_q;
default: rx_data_o = s_xfer_data_q;
3'd4: rx_data_o = {s_xfer_data_q[7:0], s_xfer_data_q[15:8], s_xfer_data_q[23:16], s_xfer_data_q[31:24]}; // HACK:
default: rx_data_o = {s_xfer_data_q[7:0], s_xfer_data_q[15:8], s_xfer_data_q[23:16], s_xfer_data_q[31:24]}; // HACK:
endcase
end
end
+3 -2
View File
@@ -8,8 +8,8 @@
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
`ifndef NATV_QSPI_DEF_SV
`define NATV_QSPI_DEF_SV
`ifndef NMI_QSPI_DEF_SV
`define NMI_QSPI_DEF_SV
// verilog_format: off
`define NATV_QSPI_MODE 8'h00
@@ -37,6 +37,7 @@
`define NATV_QSPI_HLVLEN 8'h58
`define NATV_QSPI_START 8'h5C
`define NATV_QSPI_STATUS 8'h60
`define NATV_QSPI_MMMODE 8'h64
`define QSPI_TYPE_NONE 2'd0
`define QSPI_TYPE_SNGL 2'd1
+362
View File
@@ -0,0 +1,362 @@
/*
* mt48lc16m16a2_ctrl - A sdram controller
*
* Copyright (C) 2022 Hirosh Dabui <hirosh@dabui.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
// -- Adaptable modifications are redistributed under compatible License --
//
// Copyright (c) 2023-2025 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
// ===============================
// 16Mx16 = 32MByte
// Row addressing 8k (A0-A12)
// Bank Switching 4 (BA0, BA1)
// Column Addressing 512 (A0-A8)
// ===============================
module nmi_sdram #(
parameter SDRAM_CLK_FREQ = 64,
parameter TRP_NS = 20,
parameter TRC_NS = 66,
parameter TRCD_NS = 20,
parameter TCH_NS = 2,
parameter CAS = 3'd2
) (
input wire clk,
input wire resetn,
input wire [24:0] addr,
input wire [31:0] din,
input wire [3:0] wmask,
input wire valid,
output reg [31:0] dout,
output reg ready,
output wire sdram_clk,
output wire sdram_cke,
output wire [1:0] sdram_dqm,
output wire [12:0] sdram_addr, // A0-A12 row address, A0-A8 column address
output wire [1:0] sdram_ba, // bank select A11,A12
output wire sdram_csn,
output wire sdram_wen,
output wire sdram_rasn,
output wire sdram_casn,
inout wire [15:0] sdram_dq
);
localparam ONE_MICROSECOND = SDRAM_CLK_FREQ;
localparam WAIT_100US = 100 * ONE_MICROSECOND; // 64 * 1/64e6 = 1us => 100 * 1us
// command period; PRE to ACT in ns, e.g. 20ns
localparam TRP = $rtoi((TRP_NS * ONE_MICROSECOND / 1000) + 1);
// tRC command period (REF to REF/ACT TO ACT) in ns
localparam TRC = $rtoi((TRC_NS * ONE_MICROSECOND / 1000) + 1); //
// tRCD active command to read/write command delay; row-col-delay in ns
localparam TRCD = $rtoi((TRCD_NS * ONE_MICROSECOND / 1000) + 1);
// tCH command hold time
localparam TCH = $rtoi((TCH_NS * ONE_MICROSECOND / 1000) + 1);
initial begin
$display("Clk frequence: %d MHz", SDRAM_CLK_FREQ);
$display("WAIT_100US: %d cycles", WAIT_100US);
$display("TRP: %d cycles", TRP);
$display("TRC: %d cycles", TRC);
$display("TRCD: %d cycles", TRCD);
$display("TCH: %d cycles", TCH);
$display("CAS_LATENCY: %d cycles", CAS_LATENCY);
end
localparam BURST_LENGTH = 3'b001; // 000=1, 001=2, 010=4, 011=8
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
localparam CAS_LATENCY = CAS; // 2/3 allowed, tRCD=20ns -> 3 cycles@128MHz
localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
localparam NO_WRITE_BURST = 1'b0; // 0= write burst enabled, 1=only single access write
localparam sdram_mode = {1'b0, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
//
// ISSI-IS425 datasheet page 16
// (CS, RAS, CAS, WE)
localparam CMD_MRS = 4'b0000; // mode register set
localparam CMD_ACT = 4'b0011; // bank active
localparam CMD_READ = 4'b0101; // to have read variant with autoprecharge set A10=H
localparam CMD_WRITE = 4'b0100; // A10=H to have autoprecharge
localparam CMD_BST = 4'b0110; // burst stop
localparam CMD_PRE = 4'b0010; // precharge selected bank, A10=H both banks
localparam CMD_REF = 4'b0001; // auto refresh (cke=H), selfrefresh assign cke=L
localparam CMD_NOP = 4'b0111;
localparam CMD_DSEL = 4'b1xxx;
reg [3:0] command;
reg [3:0] command_nxt;
reg cke;
reg cke_nxt;
reg [1:0] dqm;
reg [12:0] saddr;
reg [12:0] saddr_nxt;
reg [1:0] ba;
reg [1:0] ba_nxt;
assign sdram_clk = clk;
assign sdram_cke = cke;
assign sdram_addr = saddr;
assign sdram_dqm = dqm;
assign {sdram_csn, sdram_rasn, sdram_casn, sdram_wen} = command;
assign sdram_ba = ba;
// state machine stuff
localparam RESET = 0;
localparam ASSERT_CKE = 1;
localparam INIT_SEQ_PRE_CHARGE_ALL = 2;
localparam INIT_SEQ_AUTO_REFRESH0 = 3;
localparam INIT_SEQ_AUTO_REFRESH1 = 4;
localparam INIT_SEQ_LOAD_MODE = 5;
localparam IDLE = 6;
localparam COL_READ = 7;
localparam COL_READL = 8;
localparam COL_READH = 9;
localparam COL_WRITEL = 10;
localparam COL_WRITEH = 11;
localparam AUTO_REFRESH = 12;
localparam PRE_CHARGE_ALL = 13;
localparam WAIT_STATE = 14;
localparam LAST_STATE = 15;
localparam STATE_WIDTH = $clog2(LAST_STATE);
reg [STATE_WIDTH -1:0] state;
reg [STATE_WIDTH -1:0] state_nxt;
reg [STATE_WIDTH -1:0] ret_state;
reg [STATE_WIDTH -1:0] ret_state_nxt;
localparam WAIT_STATE_WIDTH = $clog2(WAIT_100US);
reg [WAIT_STATE_WIDTH -1:0] wait_states;
reg [WAIT_STATE_WIDTH -1:0] wait_states_nxt;
reg ready_nxt;
reg [31:0] dout_nxt;
reg [1:0] dqm_nxt;
reg update_ready;
reg update_ready_nxt;
reg [15:0] dq;
reg [15:0] dq_nxt;
assign sdram_dq = oe ? dq : 16'hz;
reg oe;
reg oe_nxt;
always @(posedge clk) begin
if (~resetn) begin
state <= RESET;
ret_state <= RESET;
ready <= 1'b0;
wait_states <= 0;
dout <= 0;
command <= CMD_NOP;
dqm <= 2'b11;
dq <= 0;
ba <= 2'b11;
oe <= 1'b0;
saddr <= 0;
update_ready <= 1'b0;
end else begin
dq <= dq_nxt;
dout <= dout_nxt;
state <= state_nxt;
ready <= ready_nxt;
dqm <= dqm_nxt;
cke <= cke_nxt;
command <= command_nxt;
wait_states <= wait_states_nxt;
ret_state <= ret_state_nxt;
ba <= ba_nxt;
oe <= oe_nxt;
saddr <= saddr_nxt;
update_ready <= update_ready_nxt;
end
end
always @(*) begin
wait_states_nxt = wait_states;
state_nxt = state;
ready_nxt = ready;
ret_state_nxt = ret_state;
dout_nxt = dout;
command_nxt = command;
cke_nxt = cke;
saddr_nxt = saddr;
ba_nxt = ba;
dqm_nxt = dqm;
oe_nxt = oe;
dq_nxt = dq;
update_ready_nxt = update_ready;
case (state)
RESET: begin
cke_nxt = 1'b0;
wait_states_nxt = WAIT_100US;
ret_state_nxt = ASSERT_CKE;
state_nxt = WAIT_STATE;
end
ASSERT_CKE: begin
cke_nxt = 1'b1;
wait_states_nxt = 2;
ret_state_nxt = INIT_SEQ_PRE_CHARGE_ALL;
state_nxt = WAIT_STATE;
end
INIT_SEQ_PRE_CHARGE_ALL: begin
cke_nxt = 1'b1;
command_nxt = CMD_PRE;
saddr_nxt[10] = 1'b1;
wait_states_nxt = TRP;
ret_state_nxt = INIT_SEQ_AUTO_REFRESH0;
state_nxt = WAIT_STATE;
end
INIT_SEQ_AUTO_REFRESH0: begin
command_nxt = CMD_REF;
wait_states_nxt = TRC;
ret_state_nxt = INIT_SEQ_AUTO_REFRESH1;
state_nxt = WAIT_STATE;
end
INIT_SEQ_AUTO_REFRESH1: begin
command_nxt = CMD_REF;
wait_states_nxt = TRC;
ret_state_nxt = INIT_SEQ_LOAD_MODE;
state_nxt = WAIT_STATE;
end
INIT_SEQ_LOAD_MODE: begin
command_nxt = CMD_MRS;
saddr_nxt = sdram_mode;
wait_states_nxt = TCH;
ret_state_nxt = IDLE;
state_nxt = WAIT_STATE;
end
IDLE: begin
oe_nxt = 1'b0;
dqm_nxt = 2'b11;
ready_nxt = 1'b0;
if (valid && !ready) begin
command_nxt = CMD_ACT;
ba_nxt = addr[22:21];
saddr_nxt = {addr[24:23], addr[20:10]};
wait_states_nxt = TRCD;
ret_state_nxt = |wmask ? COL_WRITEL : COL_READ;
update_ready_nxt = 1'b1;
state_nxt = WAIT_STATE;
end else begin
/* autorefresh */
command_nxt = CMD_REF;
saddr_nxt = 0;
ba_nxt = 0;
wait_states_nxt = 3; //TRC;
ret_state_nxt = IDLE;
update_ready_nxt = 1'b0;
state_nxt = WAIT_STATE;
end
end
COL_READ: begin
command_nxt = CMD_READ;
dqm_nxt = 2'b00;
saddr_nxt = {3'b001, addr[10:2], 1'b0}; // autoprecharge and column
ba_nxt = addr[22:21];
wait_states_nxt = CAS_LATENCY;
ret_state_nxt = COL_READL;
state_nxt = WAIT_STATE;
end
COL_READL: begin
command_nxt = CMD_NOP;
dqm_nxt = 2'b00;
dout_nxt[15:0] = sdram_dq;
//wait_states_nxt = TRP;
// ret_state_nxt = COL_READH;
state_nxt = COL_READH;
end
COL_READH: begin
command_nxt = CMD_NOP;
dqm_nxt = 2'b00;
dout_nxt[31:16] = sdram_dq;
wait_states_nxt = TRP;
ret_state_nxt = IDLE;
state_nxt = WAIT_STATE;
end
COL_WRITEL: begin
command_nxt = CMD_WRITE;
dqm_nxt = ~wmask[1:0];
saddr_nxt = {3'b001, addr[10:2], 1'b0}; // autoprecharge and column
ba_nxt = addr[22:21];
dq_nxt = din[15:0];
oe_nxt = 1'b1;
//wait_states_nxt = TRP;
//ret_state_nxt = COL_WRITEH;
state_nxt = COL_WRITEH;
end
COL_WRITEH: begin
command_nxt = CMD_NOP;
dqm_nxt = ~wmask[3:2];
saddr_nxt = {3'b001, addr[10:2], 1'b0}; // autoprecharge and column
ba_nxt = addr[22:21];
dq_nxt = din[31:16];
oe_nxt = 1'b1;
wait_states_nxt = TRP;
ret_state_nxt = IDLE;
state_nxt = WAIT_STATE;
end
PRE_CHARGE_ALL: begin
command_nxt = CMD_PRE;
saddr_nxt[10] = 1'b1; // select all banks
ba_nxt = 0;
wait_states_nxt = TRP;
ret_state_nxt = IDLE;
state_nxt = WAIT_STATE;
end
WAIT_STATE: begin
command_nxt = CMD_NOP;
wait_states_nxt = wait_states - 1;
if (wait_states == 1) begin
state_nxt = ret_state;
if (ret_state == IDLE && update_ready) begin
update_ready_nxt = 1'b0;
ready_nxt = 1'b1;
end
end
end
default: begin
state_nxt = state;
end
endcase
end
endmodule
-157
View File
@@ -1,157 +0,0 @@
/*
* Ravenna - A full example SoC using PicoRV32 in ASIC
*
* Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
* Copyright (C) 2018,2019 Tim Edwards <tim@efabless.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
// -- Adaptable modifications are redistributed under compatible License --
//
// Copyright (c) 2023-2025 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
`ifndef SIMP_GPIO_DEF_SV
`define SIMP_GPIO_DEF_SV
// verilog_format: off
`define SIMP_GPIO_NUM 8
`define SIMP_GPIO_DATA 8'h00
`define SIMP_GPIO_OE 8'h04
`define SIMP_GPIO_PUN 8'h08
`define SIMP_GPIO_PDN 8'h0C
// verilog_format: on
`endif
interface simp_gpio_if ();
logic [`SIMP_GPIO_NUM-1:0] gpio_out;
logic [`SIMP_GPIO_NUM-1:0] gpio_in;
logic [`SIMP_GPIO_NUM-1:0] gpio_oe;
logic [`SIMP_GPIO_NUM-1:0] gpio_pun;
logic [`SIMP_GPIO_NUM-1:0] gpio_pdn;
modport dut(output gpio_out, input gpio_in, output gpio_oe, output gpio_pun, output gpio_pdn);
endinterface
module simple_gpio (
// verilog_format: off
input logic clk_i,
input logic rst_n_i,
nmi_if.slave nmi,
simp_gpio_if.dut gpio
// verilog_format: on
);
logic s_nmi_wr_hdshk, s_nmi_rd_hdshk;
logic s_nmi_ready_d, s_nmi_ready_q;
logic s_nmi_rdata_en;
logic [31:0] s_nmi_rdata_d, s_nmi_rdata_q;
logic s_gpio_en;
logic [`SIMP_GPIO_NUM-1:0] s_gpio_d, s_gpio_q;
logic s_gpio_oe_en;
logic [`SIMP_GPIO_NUM-1:0] s_gpio_oe_d, s_gpio_oe_q;
logic s_gpio_pun_en;
logic [`SIMP_GPIO_NUM-1:0] s_gpio_pun_d, s_gpio_pun_q;
logic s_gpio_pdn_en;
logic [`SIMP_GPIO_NUM-1:0] s_gpio_pdn_d, s_gpio_pdn_q;
// HACK: because just wr/rd 8b GPIO
assign s_nmi_wr_hdshk = nmi.valid && (~s_nmi_ready_q) && nmi.wstrb[0];
assign s_nmi_rd_hdshk = nmi.valid && (~s_nmi_ready_q) && (~(|nmi.wstrb));
assign nmi.ready = s_nmi_ready_q;
assign nmi.rdata = s_nmi_rdata_q;
assign gpio.gpio_out = s_gpio_q;
assign gpio.gpio_oe = {(`SIMP_GPIO_NUM) {~rst_n_i}} | s_gpio_oe_q;
assign gpio.gpio_pun = s_gpio_pun_q;
assign gpio.gpio_pdn = s_gpio_pdn_q;
assign s_gpio_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_GPIO_DATA;
assign s_gpio_d = nmi.wdata[7:0];
dffer #(`SIMP_GPIO_NUM) u_gpio_dffer (
clk_i,
rst_n_i,
s_gpio_en,
s_gpio_d,
s_gpio_q
);
assign s_gpio_oe_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_GPIO_OE;
assign s_gpio_oe_d = nmi.wdata[7:0];
dffer #(`SIMP_GPIO_NUM) u_gpio_oe_dffer (
clk_i,
rst_n_i,
s_gpio_oe_en,
s_gpio_oe_d,
s_gpio_oe_q
);
assign s_gpio_pun_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_GPIO_PUN;
assign s_gpio_pun_d = nmi.wdata[7:0];
dffer #(`SIMP_GPIO_NUM) u_gpio_pun_dffer (
clk_i,
rst_n_i,
s_gpio_pun_en,
s_gpio_pun_d,
s_gpio_pun_q
);
assign s_gpio_pdn_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_GPIO_PDN;
assign s_gpio_pdn_d = nmi.wdata[7:0];
dffer #(`SIMP_GPIO_NUM) u_gpio_pdn_dffer (
clk_i,
rst_n_i,
s_gpio_pdn_en,
s_gpio_pdn_d,
s_gpio_pdn_q
);
assign s_nmi_ready_d = nmi.valid && (~s_nmi_ready_q);
dffr #(1) u_nmi_ready_dffr (
clk_i,
rst_n_i,
s_nmi_ready_d,
s_nmi_ready_q
);
assign s_nmi_rdata_en = s_nmi_rd_hdshk;
always_comb begin
s_nmi_rdata_d = s_nmi_rdata_q;
unique case (nmi.addr[7:0])
`SIMP_GPIO_DATA: s_nmi_rdata_d = {16'd0, s_gpio_q, gpio.gpio_in};
`SIMP_GPIO_OE: s_nmi_rdata_d = {24'd0, s_gpio_oe_q};
`SIMP_GPIO_PUN: s_nmi_rdata_d = {24'd0, s_gpio_pun_q};
`SIMP_GPIO_PDN: s_nmi_rdata_d = {24'd0, s_gpio_pdn_q};
default: s_nmi_rdata_d = s_nmi_rdata_q;
endcase
end
dffer #(32) u_nmi_rdata_dffer (
clk_i,
rst_n_i,
s_nmi_rdata_en,
s_nmi_rdata_d,
s_nmi_rdata_q
);
endmodule
@@ -30,18 +30,18 @@
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
`ifndef SIMP_TIMER_DEF_SV
`define SIMP_TIMER_DEF_SV
`ifndef NMI_TIMER_DEF_SV
`define NMI_TIMER_DEF_SV
// verilog_format: off
`define SIMP_TIMER_CFG 8'h00
`define SIMP_TIMER_RLD 8'h04
`define SIMP_TIMER_VAL 8'h08
`define NMI_TIMER_CFG 8'h00
`define NMI_TIMER_RLD 8'h04
`define NMI_TIMER_VAL 8'h08
// verilog_format: on
`endif
module simple_timer (
module nmi_timer (
// verilog_format: off
input logic clk_i,
input logic rst_n_i,
@@ -50,12 +50,13 @@ module simple_timer (
// verilog_format: on
);
// nmi
logic s_irq_d, s_irq_q;
logic s_nmi_wr_hdshk, s_nmi_rd_hdshk;
logic s_nmi_ready_d, s_nmi_ready_q;
logic s_nmi_rdata_en;
logic [31:0] s_nmi_rdata_d, s_nmi_rdata_q;
// register
logic s_tim_cfg_en;
logic [3:0] s_tim_cfg_d, s_tim_cfg_q;
logic s_tim_rld_en;
@@ -67,10 +68,9 @@ module simple_timer (
// enable interrupt on timeout
logic s_bit_en, s_bit_oneshot;
logic s_bit_updown, s_bit_irq_en;
// irq
assign irq_o = s_irq_q;
assign s_nmi_wr_hdshk = nmi.valid && (~s_nmi_ready_q) && (|nmi.wstrb);
assign s_nmi_rd_hdshk = nmi.valid && (~s_nmi_ready_q) && (~(|nmi.wstrb));
assign nmi.ready = s_nmi_ready_q;
@@ -81,8 +81,8 @@ module simple_timer (
assign s_bit_updown = s_tim_cfg_q[2];
assign s_bit_irq_en = s_tim_cfg_q[3];
assign s_tim_cfg_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_TIMER_CFG;
// register
assign s_tim_cfg_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_TIMER_CFG;
assign s_tim_cfg_d = nmi.wdata[3:0];
dffer #(4) u_tim_cfg_dffer (
clk_i,
@@ -93,7 +93,7 @@ module simple_timer (
);
assign s_tim_rld_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_TIMER_RLD;
assign s_tim_rld_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_TIMER_RLD;
always_comb begin
s_tim_rld_d = s_tim_rld_q;
if (nmi.wstrb[0]) s_tim_rld_d[7:0] = nmi.wdata[7:0];
@@ -113,7 +113,7 @@ module simple_timer (
always_comb begin
s_tim_val_d = s_tim_val_q;
s_irq_d = s_irq_q;
if (s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_TIMER_VAL) begin
if (s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_TIMER_VAL) begin
if (nmi.wstrb[0]) s_tim_val_d[7:0] = nmi.wdata[7:0];
if (nmi.wstrb[1]) s_tim_val_d[15:8] = nmi.wdata[15:8];
if (nmi.wstrb[2]) s_tim_val_d[23:16] = nmi.wdata[23:16];
@@ -165,9 +165,9 @@ module simple_timer (
always_comb begin
s_nmi_rdata_d = s_nmi_rdata_q;
unique case (nmi.addr[7:0])
`SIMP_TIMER_CFG: s_nmi_rdata_d = {28'd0, s_tim_cfg_q};
`SIMP_TIMER_RLD: s_nmi_rdata_d = s_tim_rld_q;
`SIMP_TIMER_VAL: s_nmi_rdata_d = s_tim_val_q;
`NMI_TIMER_CFG: s_nmi_rdata_d = {28'd0, s_tim_cfg_q};
`NMI_TIMER_RLD: s_nmi_rdata_d = s_tim_rld_q;
`NMI_TIMER_VAL: s_nmi_rdata_d = s_tim_val_q;
default: s_nmi_rdata_d = s_nmi_rdata_q;
endcase
end
@@ -29,17 +29,17 @@
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
`ifndef SIMP_UART_DEF_SV
`define SIMP_UART_DEF_SV
`ifndef NMI_UART_DEF_SV
`define NMI_UART_DEF_SV
// verilog_format: off
`define SIMP_UART_DIV 8'h00
`define SIMP_UART_DAT 8'h04
`define NMI_UART_DIV 8'h00
`define NMI_UART_DAT 8'h04
// verilog_format: on
`endif
module simple_uart (
module nmi_uart (
// verilog_format: off
input logic clk_i,
input logic rst_n_i,
@@ -77,7 +77,7 @@ module simple_uart (
assign uart.uart_tx_o = r_send_pattern[0];
assign uart.irq_o = r_recv_buf_valid;
assign s_uart_div_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_UART_DIV;
assign s_uart_div_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_UART_DIV;
always_comb begin
s_uart_div_d = s_uart_div_q;
if (nmi.wstrb[0]) s_uart_div_d[7:0] = nmi.wdata[7:0];
@@ -93,7 +93,7 @@ module simple_uart (
s_uart_div_q
);
assign s_uart_dat_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `SIMP_UART_DAT;
assign s_uart_dat_en = s_nmi_wr_hdshk && nmi.addr[7:0] == `NMI_UART_DAT;
assign s_send_dat_wait = s_uart_dat_en && nmi.wstrb[0] && ((|r_send_bitcnt) || r_send_dummy);
assign s_nmi_ready_d = nmi.valid && (~s_nmi_ready_q) && (~s_send_dat_wait);
dffr #(1) u_nmi_ready_dffr (
@@ -107,8 +107,8 @@ module simple_uart (
always_comb begin
s_nmi_rdata_d = s_nmi_rdata_q;
unique case (nmi.addr[7:0])
`SIMP_UART_DIV: s_nmi_rdata_d = s_uart_div_q;
`SIMP_UART_DAT: s_nmi_rdata_d = r_recv_buf_valid ? {24'd0, r_recv_buf_data} : '1;
`NMI_UART_DIV: s_nmi_rdata_d = s_uart_div_q;
`NMI_UART_DAT: s_nmi_rdata_d = r_recv_buf_valid ? {24'd0, r_recv_buf_data} : '1;
default: s_nmi_rdata_d = s_nmi_rdata_q;
endcase
end
+7 -11
View File
@@ -18,25 +18,21 @@
} while (0)
#define FLASH_SIZE (256 * 1024 * 1024) // 256MB
#define PAGE_SIZE 4096
#define PG_ALIGN __attribute((aligned(PAGE_SIZE)))
#define PAGE_SIZE 4096
#define PG_ALIGN __attribute((aligned(PAGE_SIZE)))
static inline bool in_flash(uint64_t addr) {
return (addr < FLASH_SIZE);
}
static inline bool in_flash(uint64_t addr) { return addr < FLASH_SIZE; }
static uint8_t flash[FLASH_SIZE] PG_ALIGN = {};
extern "C" void flash_read(uint64_t addr, uint64_t *data) {
extern "C" void flash_read(uint32_t addr, uint32_t *data) {
if (!data) return;
Assert(in_flash(addr), "Flash address 0x%lx out of bound", addr);
*data = *(uint64_t *)(flash + addr);
Assert(in_flash(addr), "Flash address 0x%x out of bound", addr);
*data = *(uint32_t *)(flash + addr);
}
extern "C" void flash_init(char *img) {
FILE *fp = fopen(img, "rb");
Assert(fp, "Can not open '%s'", img);
Assert(fp, "can not open '%s'", img);
fseek(fp, 0, SEEK_END);
uint64_t size = ftell(fp);
fseek(fp, 0, SEEK_SET);
+1 -1
View File
@@ -1 +1 @@
../core/picorv32.v
../core/picorv32_ver.v
-1
View File
@@ -17,4 +17,3 @@
+incdir+../../clusterip/crc/rtl
+incdir+../../clusterip/timer/rtl
+incdir+../../ip/native
+incdir+../../ip/3rd_party/spfs
+3 -16
View File
@@ -41,14 +41,6 @@
../../clusterip/timer/rtl/tmr_if.sv
../../clusterip/timer/rtl/apb4_tmr.sv
../../clusterip/spi/rtl/spi_clkgen.sv
../../clusterip/spi/rtl/spi_apb_if.sv
../../clusterip/spi/rtl/spi_ctrl.sv
../../clusterip/spi/rtl/spi_fifo.sv
../../clusterip/spi/rtl/spi_rx.sv
../../clusterip/spi/rtl/spi_tx.sv
../../clusterip/spi/rtl/spi_core.sv
../../ip/native/psram_core.sv
../../ip/native/psram.sv
../../ip/native/spisd_init.sv
@@ -74,17 +66,12 @@
../../ip/native/dma.sv
../../ip/native/sysctrl.sv
../../ip/native/clint.sv
../../ip/native/simple_timer.sv
../../ip/native/simple_uart.sv
../../ip/native/simple_gpio.sv
../../ip/native/timer.sv
../../ip/native/uart.sv
../../ip/native/gpio.sv
../../ip/native/nmi2apb.sv
../../ip/native/ahbl2nmi.sv
../../ip/native/axi4l2nmi.sv
../../ip/native/async_fifo.sv
../../ip/native/nmi_regslice.sv
../../ip/native/nmi2nmi.sv
../../ip/3rd_party/spfs/spi_clgen.v
../../ip/3rd_party/spfs/spi_shift.v
../../ip/3rd_party/spfs/spi_top.v
../../ip/3rd_party/spfs/spi_flash.v
-3
View File
@@ -1,10 +1,7 @@
+incdir+../../ip/3rd_party/spfs_model
../../clusterip/ps2/tb/kdb_model.sv
../../clusterip/i2c/model/at24cxxx.sv
../../clusterip/uart/model/rs232.sv
../../clusterip/i2s/model/mic.sv
../../clusterip/spi/model/w25q128jvxim.sv
../../ip/3rd_party/spfs_model/N25Qxxx.v
../../ip/native/ESP_PSRAM64H.sv
../tb/retrosoc_tb.sv
+1 -2
View File
@@ -2,7 +2,7 @@
../top/retrosoc.sv
../top/retrosoc_asic.sv
../top/onchip_ram.sv
../top/ip_natv_wrapper.sv
../top/ip_nmi_wrapper.sv
../top/ip_apb_wrapper.sv
../top/bus.sv
../top/rcu.sv
@@ -10,7 +10,6 @@
../top/user_core_design_template.sv
../top/user_core_top.sv
../top/user_core_wrapper.sv
../top/user_gpio.sv
../top/user_ip_design_template.sv
../top/user_ip_top.sv
../top/user_ip_wrapper.sv
+1 -1
View File
@@ -1,5 +1,5 @@
{
+lint=all;
-file=../../ip/3rd_party/spfs_model/N25Qxxx.v,../../../pdk/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_stdcell/verilog/sg13g2_stdcell.v,../../clusterip/i2c/model/at24cxxx.sv,../../clusterip/spi/model/w25q128jvxim.sv,../core/picorv32_ver.v,../core/picorv32.v,../../clusterip/common/rtl/cdc/cdc_2phase.sv,../../clusterip/common/rtl/utils/register.sv,../../clusterip/uart/model/rs232.sv,../tb/retrosoc_tb.sv,../../clusterip/i2s/model/mic.sv,../../ip/native/ESP_PSRAM64H.sv,../../ip/3rd_party/spfs_model/include/Decoders.h,../../ip/3rd_party/spfs_model/include/PLRSDetectors.h;
-file=../../../pdk/IHP-Open-PDK/ihp-sg13g2/libs.ref/sg13g2_stdcell/verilog/sg13g2_stdcell.v,../../clusterip/i2c/model/at24cxxx.sv,../../clusterip/spi/model/w25q128jvxim.sv,../core/picorv32_ver.v,../core/picorv32.v,../../clusterip/common/rtl/cdc/cdc_2phase.sv,../../clusterip/common/rtl/utils/register.sv,../../clusterip/uart/model/rs232.sv,../tb/retrosoc_tb.sv,../../clusterip/i2s/model/mic.sv,../../ip/native/ESP_PSRAM64H.sv;
}
{ +warn=all; }
+3 -7
View File
@@ -13,10 +13,9 @@ SOC_COMPILE_HOME := $(BUILD_DIR)/emu_compile
SOC_VXXFILES := $(RTL_FLIST)
SOC_VXXFILES += $(RTL_PATH)/../ip/native/ESP_PSRAM64H.sv
SOC_VXXFILES += $(shell find $(SOC_VSRC_HOME) -name "*.sv")
SOC_VXXFILES += $(RTL_PATH)/vsrc/QSPIFlash.sv
SOC_VXXFILES += $(RTL_PATH)/vsrc/retrosoc_top.sv
SOC_VSRC_INCLPATH += -I$(SOC_VSRC_HOME)
# SOC_VSRC_INCLPATH += -I$(RTL_PATH)/perip/spi/rtl
VERILATOR_CXXFLAGS += -std=c++17 -static -Wall $(SOC_CSRC_INCLPATH) -DDUMP_WAVE_FST
VERILATOR_FLAGS += --cc --exe --no-timing --top-module $(SOC_VSRC_TOP)
@@ -42,10 +41,7 @@ comp: lint
$(MAKE) VM_PARALLEL_BUILDS=1 OPT_FAST="-O3" -C $(SOC_COMPILE_HOME) -f V$(SOC_VSRC_TOP).mk -j$(nproc) > $(BUILD_DIR)/compile.log 2>&1
sim: comp
$(BUILD_DIR)/emu -i .sw_build/retrosoc_fw.bin -s $(RTL_SIM_CORESEL) -t 600
# $(BUILD_DIR)/emu -t $(SOC_SIM_TIME) -i $(RTL_PATH)/.sw_build/retrosoc_fw.bin
# $(BUILD_DIR)/emu -i app/asm/hello-asm.bin
$(BUILD_DIR)/emu -i .sw_build/retrosoc_fw.bin -s $(RTL_SIM_CORESEL) -t 100
wave:
+5 -33
View File
@@ -64,10 +64,6 @@ module retrosoc_tb;
wire s_uart1_rx;
wire s_ps2_clk;
wire s_ps2_dat;
wire s_spfs_sck;
wire s_spfs_nss;
wire s_spfs_mosi;
wire s_spfs_miso;
`ifdef HAVE_PLL
always #(1000 / XTAL_CPU_FREQ / 2) r_xtal_clk = (r_xtal_clk === 1'b0);
@@ -166,31 +162,18 @@ module retrosoc_tb;
.i2c_scl_io_pad (s_i2c_scl_io),
.i2c_sda_io_pad (s_i2c_sda_io),
.qspi_sck_o_pad (s_qspi_sck_o),
.qspi_nss0_o_pad (s_qspi_nss0_o),
.qspi_nss1_o_pad (s_qspi_nss1_o),
.qspi_nss2_o_pad (s_qspi_nss2_o),
.qspi_nss0_o_pad (s_qspi_nss0_o), // qspi flash
.qspi_nss1_o_pad (s_qspi_nss1_o), // qpi flash
.qspi_nss2_o_pad (s_qspi_nss2_o), //
.qspi_nss3_o_pad (), // tft test
.qspi_dat0_io_pad (s_qspi_dat0_io),
.qspi_dat1_io_pad (s_qspi_dat1_io),
.qspi_dat2_io_pad (s_qspi_dat2_io),
.qspi_dat3_io_pad (s_qspi_dat3_io),
.spfs_sck_o_pad (s_spfs_sck),
.spfs_nss_o_pad (s_spfs_nss),
.spfs_mosi_o_pad (s_spfs_mosi),
.spfs_miso_i_pad (s_spfs_miso)
.qspi_dat3_io_pad (s_qspi_dat3_io)
);
N25Qxxx u_N25Qxxx (
.C_ (s_spfs_sck),
.S (s_spfs_nss),
.DQ0 (s_spfs_mosi),
.DQ1 (s_spfs_miso),
.HOLD_DQ3 (),
.Vpp_W_DQ2(),
.Vcc ('d3000)
);
W25Q128JVxIM u_W25Q128JVxIM_0 (
W25Q128JVxIM u_W25Q128JVxIM_norflash (
.CSn (s_qspi_nss0_o),
.CLK (s_qspi_sck_o),
.DIO (s_qspi_dat0_io),
@@ -353,12 +336,7 @@ module retrosoc_tb;
// #1070933733; // debug spi
// #873310000;
// #340686376;
// #489238714;
// repeat (1500) begin
// repeat (5000) @(posedge r_xtal_clk);
// end
$finish;
end else if ($test$plusargs("syn_wave")) begin
$display("gen syn sim wave");
@@ -368,12 +346,6 @@ module retrosoc_tb;
#21149063;
$finish;
end
// repeat (1500) begin
// repeat (5000) @(posedge r_xtal_clk);
// $display("+5000 cycles");
// end
// $finish;
end
initial begin
+3 -25
View File
@@ -10,28 +10,6 @@
`include "mmap_define.svh"
module regslice #(
parameter int WIDTH = 1,
parameter int BYPASS = 0
) (
input logic clk_i,
input logic rst_n_i,
input logic [WIDTH-1:0] dat_i,
output logic [WIDTH-1:0] dat_o
);
if (BYPASS == 1) assign dat_o = dat_i;
else begin
dffr #(WIDTH) u_regslice_dffr (
clk_i,
rst_n_i,
dat_i,
dat_o
);
end
endmodule
module bus (
// verilog_format: off
input logic clk_i,
@@ -108,7 +86,8 @@ module bus (
// bus mux
// verilog_format: off
assign s_natv_sel = u_mstr_rgsl_nmi_if.addr[31:28] == `NATV_IP_START ||
assign s_natv_sel = u_mstr_rgsl_nmi_if.addr[31:28] == `FLASH_START ||
u_mstr_rgsl_nmi_if.addr[31:28] == `NATV_IP_START ||
u_mstr_rgsl_nmi_if.addr[31:28] == `PSRAM_START ||
u_mstr_rgsl_nmi_if.addr[31:28] == `SPISD_START0 ||
u_mstr_rgsl_nmi_if.addr[31:28] == `SPISD_START1 ||
@@ -119,8 +98,7 @@ module bus (
assign natv_nmi.wdata = u_mstr_rgsl_nmi_if.wdata;
assign natv_nmi.wstrb = u_mstr_rgsl_nmi_if.wstrb;
assign s_apb_sel = u_mstr_rgsl_nmi_if.addr[31:28] == `FLASH_START ||
u_mstr_rgsl_nmi_if.addr[31:28] == `APB_IP_START;
assign s_apb_sel = u_mstr_rgsl_nmi_if.addr[31:28] == `APB_IP_START;
assign apb_nmi.valid = u_mstr_rgsl_nmi_if.valid && s_apb_sel;
assign apb_nmi.addr = u_mstr_rgsl_nmi_if.addr;
assign apb_nmi.wdata = u_mstr_rgsl_nmi_if.wdata;
+1 -1
View File
@@ -32,7 +32,7 @@ module core_wrapper (
.ENABLE_DIV (1),
.ENABLE_IRQ (0),
.PROGADDR_RESET (`FLASH_START_ADDR),
.PROGADDR_IRQ (`IRQ_HANDLER_START_ADDR)
.PROGADDR_IRQ (`IRQ_START_ADDR)
) u_picorv32 (
.clk (clk_i),
.resetn (rst_n_i),
+3 -45
View File
@@ -9,11 +9,9 @@
// See the Mulan PSL v2 for more details.
`include "mmap_define.svh"
`include "uart_define.svh"
`include "pwm_define.svh"
`include "ps2_define.svh"
`include "mdd_config.svh"
module ip_apb_wrapper (
@@ -23,15 +21,13 @@ module ip_apb_wrapper (
input logic clk_aud_i,
input logic rst_aud_n_i,
input logic tmr_capch_i,
input logic spfs_div4_i,
nmi_if.slave nmi,
uart_if.dut uart,
pwm_if.dut pwm,
ps2_if.dut ps2,
spi_if.dut spfs,
`ifdef IP_MDD
input logic [`USER_IPSEL_WIDTH-1:0] ip_sel_i,
user_gpio_if.dut gpio,
nmi_gpio_if.dut gpio,
`endif
output logic [ 6:0] irq_o
// verilog_format: on
@@ -47,7 +43,6 @@ module ip_apb_wrapper (
apb4_if u_wdg_apb_if (clk_i, rst_n_i);
apb4_if u_crc_apb_if (clk_i, rst_n_i);
apb4_if u_tmr_apb_if (clk_i, rst_n_i);
apb4_if u_spfs_apb_if (clk_i, rst_n_i);
// NOTE: for FPGA-compatible
apb4_pure_if u_archinfo_apb_pure_if ();
@@ -59,7 +54,6 @@ module ip_apb_wrapper (
apb4_pure_if u_wdg_apb_pure_if ();
apb4_pure_if u_crc_apb_pure_if ();
apb4_pure_if u_tmr_apb_pure_if ();
apb4_pure_if u_spfs_apb_pure_if ();
// low freq clock perip
rtc_if u_rtc_if (clk_aud_i, rst_aud_n_i);
@@ -175,17 +169,6 @@ module ip_apb_wrapper (
assign u_tmr_apb_pure_if.pready = u_tmr_apb_if.pready;
assign u_tmr_apb_pure_if.prdata = u_tmr_apb_if.prdata;
assign u_tmr_apb_pure_if.pslverr = u_tmr_apb_if.pslverr;
// spfs
assign u_spfs_apb_if.paddr = u_spfs_apb_pure_if.paddr;
assign u_spfs_apb_if.pprot = u_spfs_apb_pure_if.pprot;
assign u_spfs_apb_if.psel = u_spfs_apb_pure_if.psel;
assign u_spfs_apb_if.penable = u_spfs_apb_pure_if.penable;
assign u_spfs_apb_if.pwrite = u_spfs_apb_pure_if.pwrite;
assign u_spfs_apb_if.pwdata = u_spfs_apb_pure_if.pwdata;
assign u_spfs_apb_if.pstrb = u_spfs_apb_pure_if.pstrb;
assign u_spfs_apb_pure_if.pready = u_spfs_apb_if.pready;
assign u_spfs_apb_pure_if.prdata = u_spfs_apb_if.prdata;
assign u_spfs_apb_pure_if.pslverr = u_spfs_apb_if.pslverr;
`ifdef IP_MDD
assign u_user_ip_apb_if.paddr = u_user_ip_apb_pure_if.paddr;
assign u_user_ip_apb_if.pprot = u_user_ip_apb_pure_if.pprot;
@@ -218,7 +201,7 @@ module ip_apb_wrapper (
assign irq_o[3] = u_rtc_if.irq_o;
assign irq_o[4] = u_wdg_if.rst_o;
assign irq_o[5] = u_tmr_if.irq_o;
assign irq_o[6] = spfs.irq_o;
assign irq_o[6] = 1'b0;
nmi2apb u_nmi2apb (
.clk_i (clk_i),
@@ -235,32 +218,7 @@ module ip_apb_wrapper (
.rtc (u_rtc_apb_pure_if),
.wdg (u_wdg_apb_pure_if),
.crc (u_crc_apb_pure_if),
.tmr (u_tmr_apb_pure_if),
.spfs (u_spfs_apb_pure_if)
);
spi_flash #(
.flash_addr_start(`FLASH_START_ADDR),
.flash_addr_end (`FLASH_END_ADDR),
.spi_cs_num (1)
) u_spi_flash (
.pclk (clk_i),
.presetn (rst_n_i),
.paddr (u_spfs_apb_if.paddr),
.psel (u_spfs_apb_if.psel),
.penable (u_spfs_apb_if.penable),
.pwrite (u_spfs_apb_if.pwrite),
.pwdata (u_spfs_apb_if.pwdata),
.pwstrb (4'hF),
.pready (u_spfs_apb_if.pready),
.prdata (u_spfs_apb_if.prdata),
.pslverr (u_spfs_apb_if.pslverr),
.div4_i (spfs_div4_i),
.spi_clk (spfs.spi_sck_o),
.spi_cs (spfs.spi_nss_o),
.spi_mosi (spfs.spi_mosi_o),
.spi_miso (spfs.spi_miso_i),
.spi_irq_out(spfs.irq_o)
.tmr (u_tmr_apb_pure_if)
);
`ifdef IP_MDD
@@ -11,7 +11,7 @@
// addr range: [31:28]: 4'h1(reg), 4'h4(psram), 4'h5(spisd)
`include "mmap_define.svh"
module ip_natv_wrapper (
module ip_nmi_wrapper (
// verilog_format: off
input logic clk_i,
input logic rst_n_i,
@@ -19,8 +19,8 @@ module ip_natv_wrapper (
input logic rst_aud_n_i,
// natv if
nmi_if.slave nmi,
nmi_gpio_if.dut gpio,
uart_if.dut uart,
simp_gpio_if.dut gpio,
qspi_if.dut psram,
spi_if.dut spisd,
i2c_if.dut i2c,
@@ -66,16 +66,16 @@ module ip_natv_wrapper (
assign u_dma_hw_trg_if.i2s_rx_proc = ~s_dma_i2s_rx_stall;
assign u_dma_hw_trg_if.qspi_tx_proc = ~s_dma_qspi_tx_stall;
assign u_dma_hw_trg_if.qspi_rx_proc = ~s_dma_qspi_rx_stall;
// uart
assign u_uart_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NATV_IP_START && nmi.addr[15:8] == `NMI_UART_START);
assign u_uart_nmi_if.addr = nmi.addr;
assign u_uart_nmi_if.wdata = nmi.wdata;
assign u_uart_nmi_if.wstrb = nmi.wstrb;
// gpio
assign u_gpio_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NATV_IP_START && nmi.addr[15:8] == `NMI_GPIO_START);
assign u_gpio_nmi_if.addr = nmi.addr;
assign u_gpio_nmi_if.wdata = nmi.wdata;
assign u_gpio_nmi_if.wstrb = nmi.wstrb;
// uart
assign u_uart_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NATV_IP_START && nmi.addr[15:8] == `NMI_UART_START);
assign u_uart_nmi_if.addr = nmi.addr;
assign u_uart_nmi_if.wdata = nmi.wdata;
assign u_uart_nmi_if.wstrb = nmi.wstrb;
// tim0
assign u_tim0_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NATV_IP_START && nmi.addr[15:8] == `NMI_TIM0_START);
assign u_tim0_nmi_if.addr = nmi.addr;
@@ -118,7 +118,7 @@ module ip_natv_wrapper (
assign u_onewire_nmi_if.wdata = nmi.wdata;
assign u_onewire_nmi_if.wstrb = nmi.wstrb;
// qspi
assign u_qspi_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NATV_IP_START && nmi.addr[15:8] == `NMI_QSPI_START);
assign u_qspi_nmi_if.valid = nmi.valid && ((nmi.addr[31:28] == `NATV_IP_START && nmi.addr[15:8] == `NMI_QSPI_START) | nmi.addr[31:28] == `FLASH_START);
assign u_qspi_nmi_if.addr = nmi.addr;
assign u_qspi_nmi_if.wdata = nmi.wdata;
assign u_qspi_nmi_if.wstrb = nmi.wstrb;
@@ -182,15 +182,7 @@ module ip_natv_wrapper (
assign irq_o[9] = qspi.irq_o;
simple_uart u_simple_uart (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.nmi (u_uart_nmi_if),
.uart (uart)
);
simple_gpio u_simple_gpio (
nmi_gpio u_nmi_gpio (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.nmi (u_gpio_nmi_if),
@@ -198,7 +190,15 @@ module ip_natv_wrapper (
);
simple_timer u_simple_timer0 (
nmi_uart u_nmi_uart (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.nmi (u_uart_nmi_if),
.uart (uart)
);
nmi_timer u_nmi_timer0 (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.nmi (u_tim0_nmi_if),
@@ -206,7 +206,7 @@ module ip_natv_wrapper (
);
simple_timer u_simple_timer1 (
nmi_timer u_nmi_timer1 (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.nmi (u_tim1_nmi_if),
+1 -1
View File
@@ -27,7 +27,7 @@ module mgmt_core_wrapper (
.ENABLE_DIV (1),
.ENABLE_IRQ (0),
.PROGADDR_RESET (`FLASH_START_ADDR),
.PROGADDR_IRQ (`IRQ_HANDLER_START_ADDR)
.PROGADDR_IRQ (`IRQ_START_ADDR)
) u_picorv32 (
.clk (clk_i),
.resetn (rst_n_i),
+5 -7
View File
@@ -14,7 +14,7 @@
`define FLASH_START_ADDR 32'h0000_0000
`define FLASH_END_ADDR 32'h0FFF_FFFF
// NOTE: need to set a right value for software!
`define IRQ_HANDLER_START_ADDR 32'h0000_0000
`define IRQ_START_ADDR 32'h0000_0000
`define FLASH_START 4'h0
`define NATV_IP_START 4'h1
@@ -47,11 +47,9 @@
`define APB_UART_START 8'h20
`define APB_PWM_START 8'h30
`define APB_PS2_START 8'h40
`define APB_I2C_START 8'h50
`define APB_QSPI_START 8'h60
`define APB_RTC_START 8'h70
`define APB_WDG_START 8'h80
`define APB_CRC_START 8'h90
`define APB_TMR_START 8'hA0
`define APB_RTC_START 8'h50
`define APB_WDG_START 8'h60
`define APB_CRC_START 8'h70
`define APB_TMR_START 8'h80
`define APB_USR_START 8'hF0
`endif
+5 -9
View File
@@ -18,19 +18,18 @@ module retrosoc (
input logic clk_aud_i,
input logic rst_aud_n_i,
input logic tmr_capch_i,
input logic spfs_div4_i,
input logic extn_irq_i,
`ifdef CORE_MDD
input logic [`USER_CORESEL_WIDTH-1:0] core_sel_i,
`endif
`ifdef IP_MDD
user_gpio_if.dut user_gpio,
nmi_gpio_if.dut user_gpio,
`endif
`ifdef HAVE_SRAM_IF
ram_if.master ram,
`endif
nmi_gpio_if.dut gpio,
uart_if.dut uart0,
simp_gpio_if.dut gpio,
qspi_if.dut psram,
spi_if.dut spisd,
i2c_if.dut i2c,
@@ -39,8 +38,7 @@ module retrosoc (
onewire_if.dut onewire,
uart_if.dut uart1,
pwm_if.dut pwm,
ps2_if.dut ps2,
spi_if.dut spfs
ps2_if.dut ps2
// verilog_format: on
);
@@ -97,14 +95,14 @@ module retrosoc (
);
ip_natv_wrapper u_ip_natv_wrapper (
ip_nmi_wrapper u_ip_nmi_wrapper (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.clk_aud_i (clk_aud_i),
.rst_aud_n_i(rst_aud_n_i),
.nmi (u_natv_nmi_if),
.uart (uart0),
.gpio (gpio),
.uart (uart0),
.psram (psram),
.spisd (spisd),
.i2c (i2c),
@@ -123,12 +121,10 @@ module retrosoc (
.clk_aud_i (clk_aud_i),
.rst_aud_n_i(rst_aud_n_i),
.tmr_capch_i(tmr_capch_i),
.spfs_div4_i(spfs_div4_i),
.nmi (u_apb_nmi_if),
.uart (uart1),
.pwm (pwm),
.ps2 (ps2),
.spfs (spfs),
`ifdef IP_MDD
.ip_sel_i (u_sysctrl_if.ip_sel_o),
.gpio (user_gpio),
+34 -48
View File
@@ -54,9 +54,6 @@ module retrosoc_asic (
inout tmr_capch_i_pad,
// irq
inout extn_irq_i_pad,
// uart
output uart0_tx_o_pad,
inout uart0_rx_i_pad,
// gpio
inout gpio_0_io_pad,
inout gpio_1_io_pad,
@@ -66,6 +63,9 @@ module retrosoc_asic (
inout gpio_5_io_pad,
inout gpio_6_io_pad,
inout gpio_7_io_pad,
// uart
output uart0_tx_o_pad,
inout uart0_rx_i_pad,
// psram
output psram_sck_o_pad,
output psram_nss0_o_pad,
@@ -108,11 +108,7 @@ module retrosoc_asic (
inout qspi_dat0_io_pad,
inout qspi_dat1_io_pad,
inout qspi_dat2_io_pad,
inout qspi_dat3_io_pad,
output spfs_sck_o_pad,
output spfs_nss_o_pad,
output spfs_mosi_o_pad,
inout spfs_miso_i_pad
inout qspi_dat3_io_pad
);
// clk&rst
logic s_ext_clk;
@@ -135,7 +131,7 @@ module retrosoc_asic (
`endif
`ifdef IP_MDD
user_gpio_if u_user_gpio_if ();
nmi_gpio_if #(`USER_GPIO_NUM) u_user_gpio_if ();
`endif
`ifdef HAVE_SRAM_IF
@@ -143,18 +139,17 @@ module retrosoc_asic (
`endif
// verilog_format: off
simp_gpio_if u_gpio_if ();
uart_if u_uart0_if ();
qspi_if u_psram_if ();
spi_if u_spisd_if ();
nv_i2s_if u_i2s_if ();
onewire_if u_onewire_if ();
uart_if u_uart1_if ();
pwm_if u_pwm_if ();
ps2_if u_ps2_if ();
i2c_if u_i2c_if ();
qspi_if u_qspi_if ();
spi_if u_spfs_if ();
nmi_gpio_if #(`NMI_GPIO_NUM) u_gpio_if ();
uart_if u_uart0_if ();
qspi_if u_psram_if ();
spi_if u_spisd_if ();
nv_i2s_if u_i2s_if ();
onewire_if u_onewire_if ();
uart_if u_uart1_if ();
pwm_if u_pwm_if ();
ps2_if u_ps2_if ();
i2c_if u_i2c_if ();
qspi_if u_qspi_if ();
tc_io_tri_pad u_extclk_i_pad (.pad(extclk_i_pad), .c2p(1'b0), .c2p_en(1'b0), .p2c(s_ext_clk));
@@ -196,16 +191,16 @@ module retrosoc_asic (
tc_io_tri_schmitt_pad u_tmr_capch_i_pad (.pad(tmr_capch_i_pad), .c2p(1'b0), .c2p_en(1'b0), .p2c(s_tmr_capch));
tc_io_tri_schmitt_pad u_extn_irq_i_pad (.pad(extn_irq_i_pad), .c2p(1'b0), .c2p_en(1'b0), .p2c(s_extn_irq));
// natv
tc_io_tri_full_pad u_gpio_0_io_pad (.pad(gpio_0_io_pad), .c2p(u_gpio_if.gpio_out[0]), .c2p_en(u_gpio_if.gpio_oe[0]), .p2c(u_gpio_if.gpio_in[0]), .cs(u_gpio_if.gpio_cs[0]), .pu(u_gpio_if.gpio_pu[0]), .pd(u_gpio_if.gpio_pd[0]));
tc_io_tri_full_pad u_gpio_1_io_pad (.pad(gpio_1_io_pad), .c2p(u_gpio_if.gpio_out[1]), .c2p_en(u_gpio_if.gpio_oe[1]), .p2c(u_gpio_if.gpio_in[1]), .cs(u_gpio_if.gpio_cs[1]), .pu(u_gpio_if.gpio_pu[1]), .pd(u_gpio_if.gpio_pd[1]));
tc_io_tri_full_pad u_gpio_2_io_pad (.pad(gpio_2_io_pad), .c2p(u_gpio_if.gpio_out[2]), .c2p_en(u_gpio_if.gpio_oe[2]), .p2c(u_gpio_if.gpio_in[2]), .cs(u_gpio_if.gpio_cs[2]), .pu(u_gpio_if.gpio_pu[2]), .pd(u_gpio_if.gpio_pd[2]));
tc_io_tri_full_pad u_gpio_3_io_pad (.pad(gpio_3_io_pad), .c2p(u_gpio_if.gpio_out[3]), .c2p_en(u_gpio_if.gpio_oe[3]), .p2c(u_gpio_if.gpio_in[3]), .cs(u_gpio_if.gpio_cs[3]), .pu(u_gpio_if.gpio_pu[3]), .pd(u_gpio_if.gpio_pd[3]));
tc_io_tri_full_pad u_gpio_4_io_pad (.pad(gpio_4_io_pad), .c2p(u_gpio_if.gpio_out[4]), .c2p_en(u_gpio_if.gpio_oe[4]), .p2c(u_gpio_if.gpio_in[4]), .cs(u_gpio_if.gpio_cs[4]), .pu(u_gpio_if.gpio_pu[4]), .pd(u_gpio_if.gpio_pd[4]));
tc_io_tri_full_pad u_gpio_5_io_pad (.pad(gpio_5_io_pad), .c2p(u_gpio_if.gpio_out[5]), .c2p_en(u_gpio_if.gpio_oe[5]), .p2c(u_gpio_if.gpio_in[5]), .cs(u_gpio_if.gpio_cs[5]), .pu(u_gpio_if.gpio_pu[5]), .pd(u_gpio_if.gpio_pd[5]));
tc_io_tri_full_pad u_gpio_6_io_pad (.pad(gpio_6_io_pad), .c2p(u_gpio_if.gpio_out[6]), .c2p_en(u_gpio_if.gpio_oe[6]), .p2c(u_gpio_if.gpio_in[6]), .cs(u_gpio_if.gpio_cs[6]), .pu(u_gpio_if.gpio_pu[6]), .pd(u_gpio_if.gpio_pd[6]));
tc_io_tri_full_pad u_gpio_7_io_pad (.pad(gpio_7_io_pad), .c2p(u_gpio_if.gpio_out[7]), .c2p_en(u_gpio_if.gpio_oe[7]), .p2c(u_gpio_if.gpio_in[7]), .cs(u_gpio_if.gpio_cs[7]), .pu(u_gpio_if.gpio_pu[7]), .pd(u_gpio_if.gpio_pd[7]));
tc_io_tri_pad u_uart0_tx_o_pad (.pad(uart0_tx_o_pad), .c2p(u_uart0_if.uart_tx_o), .c2p_en(1'b1), .p2c());
tc_io_tri_pad u_uart0_rx_i_pad (.pad(uart0_rx_i_pad), .c2p(1'b0), .c2p_en(1'b0), .p2c(u_uart0_if.uart_rx_i));
tc_io_tri_pad u_gpio_0_io_pad (.pad(gpio_0_io_pad), .c2p(u_gpio_if.gpio_out[0]), .c2p_en(u_gpio_if.gpio_oe[0]), .p2c(u_gpio_if.gpio_in[0]));
tc_io_tri_pad u_gpio_1_io_pad (.pad(gpio_1_io_pad), .c2p(u_gpio_if.gpio_out[1]), .c2p_en(u_gpio_if.gpio_oe[1]), .p2c(u_gpio_if.gpio_in[1]));
tc_io_tri_pad u_gpio_2_io_pad (.pad(gpio_2_io_pad), .c2p(u_gpio_if.gpio_out[2]), .c2p_en(u_gpio_if.gpio_oe[2]), .p2c(u_gpio_if.gpio_in[2]));
tc_io_tri_pad u_gpio_3_io_pad (.pad(gpio_3_io_pad), .c2p(u_gpio_if.gpio_out[3]), .c2p_en(u_gpio_if.gpio_oe[3]), .p2c(u_gpio_if.gpio_in[3]));
tc_io_tri_schmitt_pad u_gpio_4_io_pad (.pad(gpio_4_io_pad), .c2p(u_gpio_if.gpio_out[4]), .c2p_en(u_gpio_if.gpio_oe[4]), .p2c(u_gpio_if.gpio_in[4]));
tc_io_tri_schmitt_pad u_gpio_5_io_pad (.pad(gpio_5_io_pad), .c2p(u_gpio_if.gpio_out[5]), .c2p_en(u_gpio_if.gpio_oe[5]), .p2c(u_gpio_if.gpio_in[5]));
tc_io_tri_schmitt_pad u_gpio_6_io_pad (.pad(gpio_6_io_pad), .c2p(u_gpio_if.gpio_out[6]), .c2p_en(u_gpio_if.gpio_oe[6]), .p2c(u_gpio_if.gpio_in[6]));
tc_io_tri_schmitt_pad u_gpio_7_io_pad (.pad(gpio_7_io_pad), .c2p(u_gpio_if.gpio_out[7]), .c2p_en(u_gpio_if.gpio_oe[7]), .p2c(u_gpio_if.gpio_in[7]));
tc_io_tri_pad u_psram_sck_o_pad (.pad(psram_sck_o_pad), .c2p(u_psram_if.spi_sck_o), .c2p_en(1'b1), .p2c());
tc_io_tri_pad u_psram_nss0_o_pad (.pad(psram_nss0_o_pad), .c2p(u_psram_if.spi_nss_o[0]), .c2p_en(1'b1), .p2c());
tc_io_tri_pad u_psram_nss1_o_pad (.pad(psram_nss1_o_pad), .c2p(u_psram_if.spi_nss_o[1]), .c2p_en(1'b1), .p2c());
@@ -245,12 +240,9 @@ module retrosoc_asic (
tc_io_tri_pad u_qspi_dat1_io_pad (.pad(qspi_dat1_io_pad), .c2p(u_qspi_if.spi_io_out_o[1]), .c2p_en(u_qspi_if.spi_io_en_o[1]), .p2c(u_qspi_if.spi_io_in_i[1]));
tc_io_tri_pad u_qspi_dat2_io_pad (.pad(qspi_dat2_io_pad), .c2p(u_qspi_if.spi_io_out_o[2]), .c2p_en(u_qspi_if.spi_io_en_o[2]), .p2c(u_qspi_if.spi_io_in_i[2]));
tc_io_tri_pad u_qspi_dat3_io_pad (.pad(qspi_dat3_io_pad), .c2p(u_qspi_if.spi_io_out_o[3]), .c2p_en(u_qspi_if.spi_io_en_o[3]), .p2c(u_qspi_if.spi_io_in_i[3]));
tc_io_tri_pad u_spfs_sck_o_pad (.pad(spfs_sck_o_pad), .c2p(u_spfs_if.spi_sck_o), .c2p_en(1'b1), .p2c());
tc_io_tri_pad u_spfs_nss_o_pad (.pad(spfs_nss_o_pad), .c2p(u_spfs_if.spi_nss_o), .c2p_en(1'b1), .p2c());
tc_io_tri_pad u_spfs_mosi_o_pad (.pad(spfs_mosi_o_pad), .c2p(u_spfs_if.spi_mosi_o), .c2p_en(1'b1), .p2c());
tc_io_tri_pad u_spfs_miso_i_pad (.pad(spfs_miso_i_pad), .c2p(1'b0), .c2p_en(1'b0), .p2c(u_spfs_if.spi_miso_i));
// verilog_format: on
// clk buffer & mux
rcu u_rcu (
.ext_clk_i (s_ext_clk),
@@ -267,16 +259,18 @@ module retrosoc_asic (
.sys_clkdiv4_o(s_sys_clkdiv4)
);
`ifdef HAVE_SRAM_IF
onchip_ram u_onchip_ram (
.clk_i(s_sys_clk),
.ram (u_ram_if)
);
`endif
retrosoc u_retrosoc (
.clk_i (s_sys_clk),
.rst_n_i (s_sys_rst_n),
.clk_aud_i (s_aud_clk),
.rst_aud_n_i(s_aud_rst_n),
`ifdef HAVE_PLL
.spfs_div4_i(s_pll_cfg[2]),
`else
.spfs_div4_i('0),
`endif
`ifdef CORE_MDD
.core_sel_i (s_core_sel),
`endif
@@ -298,15 +292,7 @@ module retrosoc_asic (
.pwm (u_pwm_if),
.ps2 (u_ps2_if),
.i2c (u_i2c_if),
.qspi (u_qspi_if),
.spfs (u_spfs_if)
.qspi (u_qspi_if)
);
`ifdef HAVE_SRAM_IF
onchip_ram u_onchip_ram (
.clk_i(s_sys_clk),
.ram (u_ram_if)
);
`endif
endmodule
-30
View File
@@ -1,30 +0,0 @@
// Copyright (c) 2023-2025 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
`include "mdd_config.svh"
interface user_gpio_if ();
logic [`USER_GPIO_NUM-1:0] gpio_in;
logic [`USER_GPIO_NUM-1:0] gpio_out;
logic [`USER_GPIO_NUM-1:0] gpio_oe;
logic [`USER_GPIO_NUM-1:0] gpio_cs;
logic [`USER_GPIO_NUM-1:0] gpio_pu;
logic [`USER_GPIO_NUM-1:0] gpio_pd;
modport dut(
input gpio_in,
output gpio_oe,
output gpio_cs,
output gpio_pu,
output gpio_pd,
output gpio_out
);
endinterface
+6 -2
View File
@@ -25,7 +25,7 @@ module user_ip_design_template #(
// verilog_format: off
input logic clk_i,
input logic rst_n_i,
user_gpio_if.dut gpio,
nmi_gpio_if.dut gpio,
apb4_if.slave apb
// verilog_format: on
);
@@ -69,8 +69,12 @@ module user_ip_design_template #(
// NOTE: If needed, define io logic here.
// `gpio_oe` is active high, meaning gpio is
// output when `gpio_oe[x]` = 1'b1.
assign gpio.gpio_oe = '1;
assign gpio.gpio_cs = '1; // 1: CMOS 0: SCHMI
assign gpio.gpio_pu = '0;
assign gpio.gpio_pd = '0;
assign gpio.gpio_out = '0;
assign gpio.gpio_oe = '0;
// ========== USER CUSTOM AREA END ==========
// ====== INSTANCE USER CUSTOM TOP DESIGN HERE ======
+3 -3
View File
@@ -16,15 +16,15 @@ module user_ip_top (
input logic clk_i,
input logic rst_n_i,
input logic [`USER_IPSEL_WIDTH-1:0] sel_i,
user_gpio_if.dut gpio,
nmi_gpio_if.dut gpio,
apb4_if.slave apb
// verilog_format: on
);
// ====== GENERATED BY SCRIPT ======
// verilog_format: off
user_gpio_if u_user_1_gpio_if();
user_gpio_if u_user_2_gpio_if();
nmi_gpio_if u_user_1_gpio_if();
nmi_gpio_if u_user_2_gpio_if();
apb4_if u_user_1_apb_if(clk_i, rst_n_i);
apb4_if u_user_2_apb_if(clk_i, rst_n_i);
+1 -1
View File
@@ -15,7 +15,7 @@ module user_ip_wrapper (
input logic clk_i,
input logic rst_n_i,
input logic [`USER_IPSEL_WIDTH-1:0] sel_i,
user_gpio_if.dut gpio,
nmi_gpio_if.dut gpio,
apb4_if.slave apb
// verilog_format: on
);
+113
View File
@@ -0,0 +1,113 @@
`timescale 1ns / 10ps
// 1-4-4
module QSPIFlash (
input logic clk,
input logic cs,
inout wire io0,
inout wire io1,
inout wire io2,
inout wire io3
);
typedef enum logic [2:0] {
cmd_t,
addr_t,
dumm_t,
data_t,
err_t
} state_t;
reg [ 2:0] r_state;
reg [ 7:0] r_cnt;
reg [ 7:0] r_cmd;
reg [31:0] r_addr;
reg [31:0] r_data;
wire s_reset;
wire s_ren;
wire [31:0] s_rdata;
wire [31:0] s_raddr;
wire s_out_en;
assign s_reset = cs;
assign io0 = s_out_en ? r_data[28] : 1'bz;
assign io1 = s_out_en ? r_data[29] : 1'bz;
assign io2 = s_out_en ? r_data[30] : 1'bz;
assign io3 = s_out_en ? r_data[31] : 1'bz;
assign s_ren = (r_state == addr_t) && (r_cnt == 8'd24);
assign s_out_en = r_state == data_t;
assign s_raddr = r_addr;
FlashRead flashRead (
.clock (clk),
.s_ren (s_ren),
.r_addr({8'd0, s_raddr[23:0]}),
.r_data(s_rdata)
);
always @(posedge clk or posedge s_reset) begin
if (s_reset) r_state <= cmd_t;
else begin
case (r_state)
cmd_t: r_state <= r_cnt == 8'd07 ? addr_t : r_state;
addr_t: r_state <= r_cmd != 8'hEB ? err_t : (r_cnt == 8'd28) ? dumm_t : r_state;
dumm_t: r_state <= r_cnt == 8'd03 ? data_t : r_state;
data_t: r_state <= r_state;
err_t: begin
r_state <= r_state;
$error("Assertion failed: only support `EBh` read command\n");
$fatal;
end
default: r_state <= r_state;
endcase
end
end
always @(posedge clk or posedge s_reset) begin
if (s_reset) r_cnt <= 8'd0;
else begin
case (r_state)
cmd_t: r_cnt <= r_cnt == 8'd7 ? 8'd0 : r_cnt + 8'd1;
addr_t: r_cnt <= r_cnt == 8'd28 ? 8'd0 : r_cnt + 8'd4;
dumm_t: r_cnt <= r_cnt == 8'd3 ? 8'd0 : r_cnt + 8'd1;
default: r_cnt <= r_cnt + 8'd4;
endcase
end
end
always @(posedge clk or posedge s_reset) begin
if (s_reset) r_cmd <= 8'd0;
else if (r_state == cmd_t) r_cmd <= {r_cmd[6:0], io0};
end
always @(posedge clk or posedge s_reset) begin
if (s_reset) r_addr <= 32'd0;
else if (r_state == addr_t && r_cnt < 8'd24) r_addr <= {r_addr[27:0], io3, io2, io1, io0};
end
always @(posedge clk or posedge s_reset) begin
if (s_reset) r_data <= 32'd0;
else if (r_state == addr_t && r_cnt == 8'd28)
r_data <= {s_rdata[7:0], s_rdata[15:8], s_rdata[23:16], s_rdata[31:24]};
else if (r_state == data_t) r_data <= {r_data[27:0], r_data[31:28]};
end
endmodule
import "DPI-C" function void flash_read(
input int r_addr,
output int r_data
);
module FlashRead (
input clock,
input s_ren,
input [31:0] r_addr,
output reg [31:0] r_data
);
always @(posedge clock) begin
if (s_ren) flash_read(r_addr, r_data);
end
endmodule
+19 -19
View File
@@ -36,10 +36,12 @@ module retrosoc_top (
wire s_psram_dat1;
wire s_psram_dat2;
wire s_psram_dat3;
wire s_spfs_sck;
wire s_spfs_nss;
wire s_spfs_mosi;
wire s_spfs_miso;
wire s_qspi_nss0_o;
wire s_qspi_sck_o;
wire s_qspi_dat0_io;
wire s_qspi_dat1_io;
wire s_qspi_dat2_io;
wire s_qspi_dat3_io;
assign s_clk = ext_clk_i;
assign s_rst_n = rst_n_i;
@@ -124,26 +126,24 @@ module retrosoc_top (
.ps2_dat_i_pad (),
.i2c_scl_io_pad (),
.i2c_sda_io_pad (),
.qspi_sck_o_pad (),
.qspi_nss0_o_pad (),
.qspi_sck_o_pad (s_qspi_sck_o),
.qspi_nss0_o_pad (s_qspi_nss0_o),
.qspi_nss1_o_pad (),
.qspi_nss2_o_pad (),
.qspi_nss3_o_pad (),
.qspi_dat0_io_pad (),
.qspi_dat1_io_pad (),
.qspi_dat2_io_pad (),
.qspi_dat3_io_pad (),
.spfs_sck_o_pad (s_spfs_sck),
.spfs_nss_o_pad (s_spfs_nss),
.spfs_mosi_o_pad (s_spfs_mosi),
.spfs_miso_i_pad (s_spfs_miso)
.qspi_dat0_io_pad (s_qspi_dat0_io),
.qspi_dat1_io_pad (s_qspi_dat1_io),
.qspi_dat2_io_pad (s_qspi_dat2_io),
.qspi_dat3_io_pad (s_qspi_dat3_io)
);
spiFlash u_spiFlash (
.clk (s_spfs_sck),
.cs (s_spfs_nss),
.mosi(s_spfs_mosi),
.miso(s_spfs_miso)
QSPIFlash u_QSPIFlash (
.clk(s_qspi_sck_o),
.cs (s_qspi_nss0_o),
.io0(s_qspi_dat0_io),
.io1(s_qspi_dat1_io),
.io2(s_qspi_dat2_io),
.io3(s_qspi_dat3_io)
);
ESP_PSRAM64H u_ESP_PSRAM64H (
+4
View File
@@ -274,6 +274,10 @@ module tc_io_tri_full_pad (
assign p2c = pad;
`elsif PDK_IHP130
logic [2:0] dum;
assign dum[0] = cs;
assign dum[1] = pu;
assign dum[2] = pd;
(* keep *) (* dont_touch = "true" *)
sg13g2_IOPadInOut4mA u_sg13g2_IOPadInOut4mA (
.pad (pad),