[twi] added control register bit to enable/allow or disabled/not_allow SCL clock stretching by peripherals

This commit is contained in:
stnolting 2020-10-22 22:37:03 +02:00
parent 3f3f790469
commit e1212d81d4
8 changed files with 30 additions and 21 deletions

View file

@ -6,16 +6,17 @@ The latest release is [![release](https://img.shields.io/github/v/release/stnolt
A list of all releases can be found [here](https://github.com/stnolting/neorv32/releases). The most recent version of the *NEORV32 data sheet*
can be found [here](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) (pdf).
The processor can determine its version from the `mimpid` CSR (at CSR address 0xf13). A 2x4-bit decimal-coded representation is used.
Example: `CSR(mimpid) = 0x01040312 -> 01.04.03.12 -> Version 1.4.3.12 = v1.4.3.12`
The processor can determine its version from the `mimpid` CSR (at CSR address 0xf13). A 2x4-bit decimal-coded representation is used. Leading
zeros are optional. Example: `CSR(mimpid) = 0x01040312 -> 01.04.03.12 -> Version 1.4.3.12 = v1.4.3.12 = v01.04.03.12`
For the HDL sources the version number is globally defined by the `hw_version_c` constant in the main VHDL package file
[`rtl/core/neorv32_package.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_package.vhd).
| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 22.10.2020 | 1.4.5.11 | TWI: Added new control register flag to enable/disable clock stretching by peripheral devices |
| 22.10.2020 | 1.4.5.10 | Added `i_bus_priv_o` and `d_bus_priv_o` signals to CPU_top and `priv_o` to Processor_top to show privilege level of bus access (from `mstatus` MPP); :warning: Fixed bug in external memory interface [WISHBONE] (non-standard Wishbone components were able to corrupt processor-internal ACK/ERR signal logic) |
| 20.10.2020 | 1.4.5.9 | Fixed bug in CPU "sleep" instruction (`WFI` - wait for interrupt) |
| 20.10.2020 | 1.4.5.9 | :warning: Fixed bug in CPU "sleep" instruction (`WFI` - wait for interrupt) |
| 20.10.2020 | 1.4.5.8 | *Machine timer interrupt* is available as processor input pin (`mtime_irq_i`) if internal `MTIME` is not implemented (`IO_MTIME_USE` = false) |
| 18.10.2020 | 1.4.5.7 | Added new IO peripheral/Device: Second CFU (CFU1); renamed old CFU to CFU0; CFU VHDL files: `neorv32_cfu0.vhd` & `neorv32_cfu1.vhd`; removed CFU interrupt |
| 17.10.2020 | 1.4.5.5 | New makefile target `upload` allows to directly upload an executable to the bootloader from the console |
@ -29,16 +30,16 @@ For the HDL sources the version number is globally defined by the `hw_version_c`
| 08.10.2020 | 1.4.4.5 | Removed CPU's `BUS_TIMEOUT` and processor's `MEM_EXT_TIMEOUT` generics; instead, a global configuration `bus_timeout_c` in the VHDL package file is used now |
| 08.10.2020 | 1.4.4.4 | Removed `DEVNULL` device; all simulation output options from this device are now available as `SIM_MODE` in the `UART`; `mcause` CSR can now also be written; FIXED: trying to write a read-only CSR will cause an illegal instruction exception; for compatibility reasons any write access to the misa CSR will be ignored and will NOT cause an exception |
| 07.10.2020 | 1.4.4.2 | Simplified ALU's set of core operations; removed co-processor data mux right after ALU -> shorter critical path; CPU control VHDL code clean-up and CSR write logic optimization; optimized IMEM/DMEM access logic; added note regarding alignment of IMEM/DMEM |
| 05.10.2020 | [**:rocket:1.4.4.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.4.0) | Fixed bug in external memory interface: Executing code from external memory was causing an instruction fetch stall |
| 05.10.2020 | [**:rocket:1.4.4.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.4.0) | :warning: Fixed bug in external memory interface: Executing code from external memory was causing an instruction fetch stall |
| 02.10.2020 | 1.4.3.9 | `[m]cycleh` and `[m]instreth` CSRs are now 32-bit wide (-> fully RISC-V-compliant) |
| 01.10.2020 | 1.4.3.8 | Added CPU top entity wrapper with resolved port signals `rtl/top_templetes/neorv32_cpu_stdlogic.vhd`; optimized ALU core functions shorter critical path, less control overhead, reduced HW footprint |
| 27.09.2020 | 1.4.3.3 | Further improved ALU and control logic; CSR access instruction require one additional cycle now (to let side effects kick in); updated synthesis results; added CFU hardware driver dummy |
| 26.09.2020 | 1.4.3.2 | Fixed bug in `CSRRWI` instruction (introduced with version 1.4.3.1); further ALU operand logic optimizations; updated CPU data path figure |
| 26.09.2020 | 1.4.3.2 | :warning: Fixed bug in `CSRRWI` instruction (introduced with version 1.4.3.1); further ALU operand logic optimizations; updated CPU data path figure |
| 25.09.2020 | 1.4.3.1 | Register file's `x0` is now a physical register; this register is initialized by the hardware and locked afterwards; removed "set to zero" stage -> smaller hardware footprint and shorter critical path; added processor top entity wrapper with resolved signals `rtl/top_templetes/neorv32_top_stdlogic.vhd` |
| 16.09.2020 | [**:rocket:1.4.3.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.3.0) | Simplified memory configuration: removed processor top's memory space configuration generics (`MEM_ISPACE_BASE`, `MEM_ISPACE_SIZE`, `MEM_DSPACE_BASE`, `MEM_DSPACE_SIZE`); data/instruction space sizes are irrelevant for hardware; instruction/data space base addresses are fixed (but can be modified in NEORV32 VHDL package file); modified SYSINFO registers; adapted bootloader, crt0 start-up code and linker script; stack configuration is now done via linker script; reworked chapter "address space"; added CFU interrupt -> fast interrupt channel 1 (shared with GPIO) |
| 14.09.2020 | 1.4.2.0 | Removed option to disable CSR counters (via `CSR_COUNTERS_USE` generic) since these counters are mandatory according to the RISC-V specs; added new IO/peripheral device: custom functions unit (`CFU`) for tightly-coupled custom co-processors; improved timing of processor-internal clock generator; fixed wrong labels in address space figure and removed dedicated exception vectors box; added mask register to GPIO unit to specify which input pins can trigger a pin-change interrupt |
| 11.09.2020 | 1.4.0.4 | Reworked `TRNG` architecture and interface; added text regarding fast interrupt channels usage for the NEORV32 processor |
| 02.09.2020 | 1.4.0.2 | Fixed bugs in external memory interface; added option to define latency of simulated external memory in testbench; hardware configuration sanity checks will now only appear once in console; added more details to data sheet section 3.3. Address Space; fixed typos in MEM_*_BASE and MEM_*_SIZE generic names |
| 02.09.2020 | 1.4.0.2 | :warning: Fixed bugs in external memory interface; added option to define latency of simulated external memory in testbench; hardware configuration sanity checks will now only appear once in console; added more details to data sheet section 3.3. Address Space; fixed typos in MEM_*_BASE and MEM_*_SIZE generic names |
| 01.09.2020 | 1.4.0.1 | Using registers above `x15` when the `E` extensions is enabled will now correctly cause an illegal instruction exception |
| 29.08.2020 | [**:rocket:1.4.0.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.0.0) | Rearranged and reworked this document; added FreeRTOS port, demo & short referencing chapter; removed booloader-specific linker scripts main linker script is used for both, applications and bootloader; bootloader can now have `.data` and `.bss` sections; improved IMEM and BOOTROM memory initialization faster synthesis; image generator now constrains init array size to actual executable size; peripheral/IO devices can only be written in full word mode (= 32-bit); GPIO ports are now 32-bit wide |
| 23.08.2020 | 1.3.7.3 | Added custom `mzext` CSR to check for available Z* CPU extensions; multiplier's FAST_MUL mode is one cycle faster now; updated performance data |
@ -47,8 +48,8 @@ For the HDL sources the version number is globally defined by the `hw_version_c`
| 06.08.2020 | 1.3.6.5 | Added `FAST_MUL_EN` generic to enable mapping of the multiplier core to DSP blocks; ALU.shifter is no more triggered when executing MULDIV operations; added benchmark results for DSP-based multiplier configurations; updated implementation and performance results; simplified makefiles using implicit libc definition; crt0 only initializes lowest 16 registers |
| 03.08.2020 | [**:rocket:1.3.6.0**](https://github.com/stnolting/neorv32/releases/tag/v1.3.6.0) | Relocated `DEVNULL` (changed base address); minor edits, optimization and clean-ups |
| 30.07.2020 | 1.3.5.2 | Added register stage to PMP mask generation to shorten critical path; removed automatic IRQ enable/disable from RTE install/uninstall functions |
| 30.07.2020 | 1.3.5.1 | Fixed bug(s) in PMP mask generation; `misa.Z` flag is not yet defined by the RISC-V specs., hence it is read-only and read as zero |
| 29.07.2020 | 1.3.5.0 | Added user privilege level, enabled via new `CPU_EXTENSION_RISCV_U` generic; fixed error in `mstatus(mpie)` logic; implemented RISC-V spec.-compliant Physical Memory Protection (PMP); allows up to 8 regions but only NAPOT mode is supported yet |
| 30.07.2020 | 1.3.5.1 | :warning: Fixed bug(s) in PMP mask generation; `misa.Z` flag is not yet defined by the RISC-V specs., hence it is read-only and read as zero |
| 29.07.2020 | 1.3.5.0 | Added user privilege level, enabled via new `CPU_EXTENSION_RISCV_U` generic; :warning: fixed error in `mstatus(mpie)` logic; implemented RISC-V spec.-compliant Physical Memory Protection (PMP); allows up to 8 regions but only NAPOT mode is supported yet |
| 25.07.2020 | 1.3.0.0 | `mcause` CSR is read-only now!; removed `CLIC`, added 4 fast IRQ channels to CPU with according flags in `mie` and `mip` and trap IDs; updated core libraries; updated NEORV32 RTE; highly reworked data sheet; updated synthesis and performance results |
| 21.07.2020 | 1.2.0.6 | Added doc section regarding the CPU's data and instruction interfaces; optimized CPU fetch engine; updated iCE40 synthesis results |
| 20.07.2020 | 1.2.0.5 | Less penalty for taken branches and jumps (2 cycles faster) |
@ -57,6 +58,6 @@ For the HDL sources the version number is globally defined by the `hw_version_c`
| 10.07.2020 | 1.0.6.0 | Non-taken branches are now 1 cycle faster; the `time[h]` CSR now correctly reflects the system time from the MTIME unit; fixed WFI instruction permanently stalling the CPU; `[m]cycle[h]` counters now stop counting when CPU is in sleep mode; `minstret[h]` and `mcycle[h]` now also allow write-access |
| 09.07.2020 | 1.0.5.0 | `X` flag of `misa` CSR is zero now; the default SPI flash boot address of the bootloader is now `0x0080000`; new exemplary FPGA utilization results for Intel, Lattice and Xilinx; `misa` CSR is read-only again, switching compressed extension on/off is pretty bad for the fetch engine; `mtval` and `mcause` CSRs now allow write accesses and are finally RISC-V-compliant; time low and high registers of `MTIME` peripheral can now also be written by user; `MTIME` registers only allow full-word write accesses |
| 06.07.2020 | 1.0.1.0 | Added missing `fence` instruction; added new generic to enable optional Zifencei CPU extension for instruction stream synchronization |
| 05.07.2020 | 1.0.0.0 | New CPU architecture: Fetch and execute engines; increased CPI; timer and counter CSRs are now all 64-bit wide; fixed CSR access errors; fixed `C.LW` decompression logic; `misa` flags `C` and `M` are now r/w compressed mode and multiplier/divider support can be switched on/off during runtime; PC(0) is now always zero; fixed bug in multiplier/divider co-processor; renamed SPI signals; added RISC-V compliance check information processor now passes the official RISC-V compliance tests |
| 05.07.2020 | 1.0.0.0 | New CPU architecture: Fetch and execute engines; increased CPI; timer and counter CSRs are now all 64-bit wide; :warning: fixed CSR access errors; fixed `C.LW` decompression logic; `misa` flags `C` and `M` are now r/w compressed mode and multiplier/divider support can be switched on/off during runtime; PC(0) is now always zero; :warning: fixed bug in multiplier/divider co-processor; renamed SPI signals; added RISC-V compliance check information processor now passes the official RISC-V compliance tests |
| 25.06.2020 | 0.0.2.5 | Added `DEVNULL` device; added chapter regarding processor simulation; fixed/added links; fixed typos; added FPGA implementation results for iCE40 UP |
| 23.06.2020 | [**:rocket:0.0.2.3**](https://github.com/stnolting/neorv32/releases/tag/v1.2.0.5) | Publication |

Binary file not shown.

View file

@ -41,7 +41,7 @@ package neorv32_package is
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- data width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01040510"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01040511"; -- no touchy!
constant pmp_max_r_c : natural := 8; -- max PMP regions - FIXED!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!

View file

@ -74,11 +74,12 @@ architecture neorv32_twi_rtl of neorv32_twi is
constant ctrl_twi_en_c : natural := 0; -- r/w: TWI enable
constant ctrl_twi_start_c : natural := 1; -- -/w: Generate START condition
constant ctrl_twi_stop_c : natural := 2; -- -/w: Generate STOP condition
constant ctrl_twi_irq_en_c : natural := 3; -- r/w: transmission done interrupt
constant ctrl_twi_irq_en_c : natural := 3; -- r/w: Enable transmission done interrupt
constant ctrl_twi_prsc0_c : natural := 4; -- r/w: CLK prsc bit 0
constant ctrl_twi_prsc1_c : natural := 5; -- r/w: CLK prsc bit 1
constant ctrl_twi_prsc2_c : natural := 6; -- r/w: CLK prsc bit 2
constant ctrl_twi_mack_c : natural := 7; -- r/w: generate ACK by controller for transmission
constant ctrl_twi_cksten_c : natural := 8; -- r/w: enable clock stretching by peripheral
--
constant ctrl_twi_ack_c : natural := 30; -- r/-: Set if ACK received
constant ctrl_twi_busy_c : natural := 31; -- r/-: Set if TWI unit is busy
@ -98,7 +99,7 @@ architecture neorv32_twi_rtl of neorv32_twi is
signal twi_clk_halt : std_ulogic;
-- twi transceiver core --
signal ctrl : std_ulogic_vector(7 downto 0); -- unit's control register
signal ctrl : std_ulogic_vector(8 downto 0); -- unit's control register
signal arbiter : std_ulogic_vector(2 downto 0);
signal twi_bitcnt : std_ulogic_vector(3 downto 0);
signal twi_rtx_sreg : std_ulogic_vector(8 downto 0); -- main rx/tx shift reg
@ -141,6 +142,7 @@ begin
data_o(ctrl_twi_prsc1_c) <= ctrl(ctrl_twi_prsc1_c);
data_o(ctrl_twi_prsc2_c) <= ctrl(ctrl_twi_prsc2_c);
data_o(ctrl_twi_mack_c) <= ctrl(ctrl_twi_mack_c);
data_o(ctrl_twi_cksten_c) <= ctrl(ctrl_twi_cksten_c);
--
data_o(ctrl_twi_ack_c) <= not twi_rtx_sreg(0);
data_o(ctrl_twi_busy_c) <= arbiter(1) or arbiter(0);
@ -272,12 +274,13 @@ begin
-- Clock Stretching Detector --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
clock_stretching: process(arbiter, twi_scl_o, twi_scl_i_ff1)
clock_stretching: process(ctrl, arbiter, twi_scl_o, twi_scl_i_ff1)
begin
-- clock stretching by the peripheral can happen at "any time"
if (arbiter(2) = '1') and -- module enabled
(twi_scl_o = '1') and -- controller wants to pull scl high
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by peripheral
if (arbiter(2) = '1') and -- module enabled
(ctrl(ctrl_twi_cksten_c) = '1') and -- clock stretching enabled
(twi_scl_o = '1') and -- controller wants to pull scl high
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by peripheral
twi_clk_halt <= '1';
else
twi_clk_halt <= '0';

View file

@ -101,8 +101,8 @@ int main() {
neorv32_uart_printf("This program allows to create TWI transfers by hand.\n"
"Type 'help' to see the help menu.\n\n");
// configure TWI, second slowest clock, no IRQ
neorv32_twi_setup(CLK_PRSC_2048, 0);
// configure TWI, second slowest clock, no IRQ, no clock-stretching
neorv32_twi_setup(CLK_PRSC_2048, 0, 0);
// no active bus session yet
bus_claimed = 0;

View file

@ -423,6 +423,7 @@ enum NEORV32_TWI_CT_enum {
TWI_CT_PRSC1 = 5, /**< TWI control register(5) (r/w): Clock prescaler select bit 1 */
TWI_CT_PRSC2 = 6, /**< TWI control register(6) (r/w): Clock prescaler select bit 2 */
TWI_CT_MACK = 7, /**< TWI control register(7) (r/w): Generate controller ACK for each transmission */
TWI_CT_CKSTEN = 8, /**< TWI control register(8) (r/w): Enable clock stretching (by peripheral) */
TWI_CT_ACK = 30, /**< TWI control register(30) (r/-): ACK received when set */
TWI_CT_BUSY = 31 /**< TWI control register(31) (r/-): Transfer in progress, busy flag */

View file

@ -46,7 +46,7 @@
// prototypes
int neorv32_twi_available(void);
void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en);
void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en, uint8_t ckst_en);
void neorv32_twi_disable(void);
void neorv32_twi_mack_enable(void);
int neorv32_twi_busy(void);

View file

@ -66,8 +66,9 @@ int neorv32_twi_available(void) {
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
* @param[in] irq_en Enable transfer-done interrupt when 1.
* @param[in] ckst_en Enable clock-stretching by peripherals when 1.
**************************************************************************/
void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en) {
void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en, uint8_t ckst_en) {
TWI_CT = 0; // reset
@ -80,7 +81,10 @@ void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en) {
uint32_t ct_irq = (uint32_t)(irq_en & 0x01);
ct_irq = ct_irq << TWI_CT_IRQ_EN;
TWI_CT = ct_enable | ct_prsc | ct_irq;
uint32_t ct_cksten = (uint32_t)(ckst_en & 0x01);
ct_cksten = ct_cksten << TWI_CT_CKSTEN;
TWI_CT = ct_enable | ct_prsc | ct_irq | ct_cksten;
}