mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-05 06:32:37 +00:00
57 files changed
+1139
-16847
No files matched your search
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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", ®_gpio_data);
|
||||
printf(" 8 x GPIO @0x%x\n", ®_gpio_oe);
|
||||
printf(" 1 x UART0 @0x%x\n", ®_uart0_clkdiv);
|
||||
printf(" 2 x TIMER(0,1) @0x%x,0x%x\n", ®_tim0_cfg, ®_tim1_cfg);
|
||||
printf(" 1 x PSRAM @0x%x\n", ®_psram_wait);
|
||||
printf(" 1 x SPISD @0x%x\n", ®_spisd_mode);
|
||||
printf(" 1 x I2C0 @0x%x\n", ®_i2c0_clkdiv);
|
||||
printf(" 1 x SPISD/SDIO @0x%x\n", ®_spisd_mode);
|
||||
printf(" 1 x I2C @0x%x\n", ®_i2c0_clkdiv);
|
||||
printf(" 1 x I2S @0x%x\n", ®_i2s_mode);
|
||||
printf(" 1 x ONEWIRE @0x%x\n", ®_onewire_clkdiv);
|
||||
printf(" 1 x QSPI0 @0x%x\n", ®_qspi0_mode);
|
||||
printf(" 1 x XPI @0x%x\n", ®_qspi0_mode);
|
||||
printf(" 1 x DMA @0x%x\n", ®_dma_mode);
|
||||
printf(" 1 x SYSCTRL @0x%x\n", ®_sysctrl_coresel);
|
||||
printf(" 1 x CLINT @0x%x\n", ®_clint_clkdiv);
|
||||
printf(" 1 x CLINT @0x%x\n", ®_clint_mtimel);
|
||||
printf(" 1 x SDRAM @0x%x\n", ®_sdram_cfg);
|
||||
printf(" 1 x ARCHINFO @0x%x\n", ®_archinfo_sys);
|
||||
printf(" 1 x RNG @0x%x\n", ®_rng_ctrl);
|
||||
printf(" 1 x UART1(ADV) @0x%x\n", ®_uart1_lcr);
|
||||
printf(" 4 x PWM @0x%x\n", ®_pwm_ctrl);
|
||||
printf(" 1 x PS2 @0x%x\n", ®_ps2_ctrl);
|
||||
printf(" 1 x I2C1(ADV) @0x%x\n", ®_i2c1_ctrl);
|
||||
printf(" 1 x QSPI1 @0x%x\n", ®_qspi1_status);
|
||||
printf(" 1 x RTC @0x%x\n", ®_rtc_ctrl);
|
||||
printf(" 1 x WDG @0x%x\n", ®_wdg_ctrl);
|
||||
printf(" 1 x CRC @0x%x\n", ®_crc_ctrl);
|
||||
|
||||
+18
-27
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Vendored
-82
@@ -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
|
||||
Vendored
-119
@@ -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
|
||||
Vendored
-240
@@ -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
|
||||
Vendored
-199
@@ -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
|
||||
|
||||
Vendored
-229
@@ -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
|
||||
|
||||
-10962
File diff suppressed because it is too large.
Load diff
-1326
File diff suppressed because it is too large.
Load diff
-2223
File diff suppressed because it is too large.
Load diff
-260
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 @@
|
||||
../core/picorv32.v
|
||||
../core/picorv32_ver.v
|
||||
@@ -17,4 +17,3 @@
|
||||
+incdir+../../clusterip/crc/rtl
|
||||
+incdir+../../clusterip/timer/rtl
|
||||
+incdir+../../ip/native
|
||||
+incdir+../../ip/3rd_party/spfs
|
||||
+3
-16
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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; }
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 ======
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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
|
||||
@@ -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 (
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in new issue
Block a user