Giter VIP home page Giter VIP logo

caravel_openframe_project's Introduction

OpenFrame Project Example

The OpenFrame Project Example is a user project designed to showcase how to use the Caravel "OpenFrame" design, which is an alternative user project harness chip that differs from the Caravel and Caravan designs by (1) having no integrated SoC on chip, (2) allowing access to all GPIO controls, (3) maximizing the user project area, and (4) minimizing the support circuitry to comprise only the padframe, a power-on-reset circuit, and a digital ROM containing the 32-bit project ID. The padframe design and placement of pins matches the Caravel and Caravan chips. The pin types also remain the same, with power and ground pins in the same positions, with the same power domains available. Pins which previously had functions connected with the CPU (flash controller interface, SPI interface, UART) use the same GPIO pads but allocate them to general-purpose I/O for any purpose.

One reason for choosing the Openframe harness is to implement an alternative SoC or implement an SoC with the user project integrated into the same level of hierarchy. This project example demonstrates that approach, where the VexRISC CPU from the Caravel and Caravan chips is replaced with a PicoRV32, which is the same processor core that was used on the first Caravel design from MPW-one. To facilitate testing, the design maintains the same special-purpose pins used by Caravel and Caravan, such as (critially) the flash controller and housekeeping SPI, so that the chip after fabrication will be fully compatible with the development board shipped by Efabless with the chips.

The primary difference between this Openframe project example and the original MPW-one Caravel design is that there is no user project in the middle, since the whole thing is now the user project. Interfaces that existed between the SoC core and user project, such as the logic analyzer, have no meaning in this context and are eliminated. The Wishbone address space to the user project is eliminated, but the design is free to add any additional Wishbone modules at any valid memory map location. The GPIOs are no longer shared between the CPU and the user project. Each GPIO is therefore configured individually, with a separate Wishbone interface connecting to each one for configuration and I/O.

Otherwise, this project example does not seek to provide additional components above and beyond what was already on the Caravel harness chip, which includes the flash controller, UART, an SPI master, two counter/timers, housekeeping SPI, and digital locked loop (DLL). It provides only one new module that groups GPIO signals into a vector that can be written or read at the same time; that module recovers the function of simultaneous GPIO reads and writes that was handled in Caravel and Caravan by the housekeeping module, but was eliminated by moving GPIO configuration to individual Wishbone interfaces.

This README file provides basic information about the project's features, configurations, and usage. Complete documentation can be found in the file docs/caravel_openframe_datasheet.pdf. The datasheet does not contain information about architecting or hardening the design.

Table of Contents

  • Module Overview
  • Designing
  • Building
  • Submitting
  • Contributing
  • License

Module Overview

The OpenFrame project example is built around the PicoRV32 CPU from YosysHQ, specifically the version which utilizes the Wishbone interface to communicate with various modules. This project example includes the following IPs, listed with their respective base addresses:

  • RAM: 0x00000000
  • FLASH: 0x10000000
  • UART: 0x20000000
  • GPIO: 0x21000000
  • Counter Timer 0: 0x22000000
  • Counter Timer 1: 0x23000000
  • SPI Master: 0x24000000
  • GPIO Vector: 0x25000000
  • Flash Controller: 0x2D000000
  • Debug Registers: 0x41000000

Additionally, the project includes a "housekeeping" module that is accessed by SPI protocol for DLL configuration, chip information, and flash programming. This IP is not accessible through the Wishbone bus in this version, but is indirectly accessible by coupling internally to the SPI master.

Designing

The main challenge of architecting an Openframe project is understanding the GPIO pad interface, which is quite complicated. The Caravel and Caravan designs purposefully kept details away from the end user. This example presents a similar solution in which each GPIO pad is interfaced by an independent Wishbone interface (gpio_wb.v). Each GPIO has I/O similar to the user project connections on Caravel and Caravan, but with a four-signal interface that adds the input disable pin (cpu_gpio_ieb) to the common three-pin interface with output disable (cpu_gpio_oeb), output (cpu_gpio_out), and input (cpu_gpio_in). The remaining configuration options for the GPIO pad are handled through Wishbone writes. The Wishbone interface additionally allows the three I/O signals to be overridden by an internal register value.

Any additions to the Wishbone bus need to be added to the Wishbone address interpreter (intercon_wb.v). Note that this has been done differently for the GPIO modules so that all of the GPIO wishbone instances (one per GPIO pin) can act as a single wishbone interface; each instance decodes only its own address, and all GPIO instances share the GPIO data bus and acknowledge signal.

Where on Caravel, the default configuration of each GPIO pin at power-up is declared in a separate file, here the default configuration data is kept as a parameter array (picosoc.v) and applied to each GPIO wishbone instance.

The "cpu_gpio_*" pins on the GPIO wishbone interface (see above) define a "standard function" for each GPIO pin (such as SPI master pins, UART transmit/receive, etc.). Since many of these GPIO do not change configuration (are always either input or output), the input and output disables, and sometimes the output value, are fixed constant high or low. For this purpose, each pad provides an individual pair of pins "gpio_loopback_zero" and "gpio_loopback_one" that are placed next to the pad and should be used for applying constant values to pad-related signals.

The loopback constants can also be used to blanket disable specific unneeded functions of the GPIO pins. In openframe_project_wrapper.v, they have been used to disable the obscure inputs "gpio_analog_*" (an interface to a switched-capacitor analog bus pair) and "gpio_holdover" (related to a sleep state that possibly cannot be achieved given the wiring inside the padframe).

The hierarchy of the Openframe project is:

Top level: openframe_project_wrapper.v. This must always be the name of the top level cell, as it is what gets integrated into the Openframe design to create the completed chip. The openframe_project_wrapper module instantiates the SoC and ties off (or leaves unconnected) pins unused by the SoC.

Second level: picosoc.v. This is the SoC definition. It instantiates all of the blocks of the SoC as Wishbone components: The CPU (picorv32_wb), the SPI flash controller (spimemio_wb), the UART (simpleuart_wb), SRAM (mem_wb), and others. It defines all of the wiring to the I/Os. It also defines a few modules that have not (by design choice) been implemented as Wishbone components: The housekeeping module (housekeeping), the DLL (digital_locked_loop), and the clock and reset routing and synchronization (clock_routing).

Third level: All SoC modules.

Power domain considerations:

This design example connects the entire user project design to the vccd1/vssd1 domain using power connection cells (with verilog, layout, abstract, etc. views) that are treated as macros and placed at the appropriate position in the layout to connect between the padframe power pads and the power ring surrounding the synthesized digital core. In general, however, it is preferable to connect together as many domains as possible to maximize the amount of current delivered to the project and minimize the amount of I-R drop from the pads to any point in the core. The 3.3-5.0V domains (vdda/vssa, vdda1/vssa1, vdda2/vssa2, vddio/vssio) should be kept separate from the 1.8V domains (vccd/vssd, vccd1/vssd1, vccd2/vssd2), but otherwise the user is encouraged to short together all the 1.8V domains and optionally (if used) the 3.3V domains with the exception of vddio/vssio, which is the ESD supply for the padframe and should remain isolated.

Analog and mixed-signal designs:

Analog designs may make use of Openframe, but since there is no Caravan-equivalent of Openframe with bare analog pads, any analog signals in the Openframe design must connect to the GPIO pads, which limits them to the voltage range of (vddio, vssio), and limits the frequency to approximately 60MHz. All GPIOs connected to analog signals must have the input and output buffers disabled.

The two choices of connections for analog signals to a GPIO pad are (1) the analog_io[] pins, which connect to the pad through a resistor and are the preferred connection, having some ESD protection; and (2) the analog_noesd_io[] pins, which connect directly to the pad and are very ESD sensitive. They should not be used unless the signal in question cannot tolerate the voltage drop across the ESD protection resistor on the analog_io[] pin.

Analog circuits that need 3.3V-5.0V compatible digital controls can make use of the gpio_in_h digital inputs from the GPIO pins, which are in the high voltage domain. However, there is no equivalent GPIO high voltage output, so any outputs in a high voltage domain must be level-shifted to 1.8V before connecting to a gpio_out[] pin.

Caravel board compatibility:

To keep compatibility with the caravel circuit board, projects should note which pins connect on the board to other (potentially) driving circuitry: Pins gpio[1] through gpio[4] connect to the FTDI chip (used by the housekeeping SPI on Caravel, and which can theoretically be placed into a high-impedence state through software). Pin gpio[38] connects to the CMOS clock (which can be disabled to a high impedence state with a jumper); pins gpio[39] to gpio[42] connect directly to the SPI flash chip and can only be disconnected by desoldering the SPI flash chip; and pin gpio[43] is connected to an LED. Pins gpio[5] and gpio[6] connect to switches which allow them to be connected to the FTDI (UART function) but will normally be in a high-impedence state. All other GPIO pins connect only to header pins on the development board.

Building

For instructions on building (hardening) the OpenFrame Example project, please refer to the [README](./README) containing the build notes.

This project example was built using locally installed tools and not with docker. Instructions are specific to my local build environment but hopefully with enough commentary to be more generally useful. It should also be possible to build the project in the Efabless-recommended docker environment.

Submitting

(To be completed)

Contributing

Bug fixes are always welcome. Enhancements will be considered if they demonstrate some useful technique that can only be achieved with the Openframe version. Otherwise, this project example is meant to be just that---an example to learn from and build on for your own Openframe project. The best way to contribute is to create your own open source Openframe project for a ChipIgnite shuttle run.

License

The Caravel Openframe harness chip design on which this example depends is distributed under the Apache-2.0 license. This project example is also distributed under the Apache-2.0 license (see the LICENSE file).

caravel_openframe_project's People

Contributors

m0stafarady avatar rtimothyedwards avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

caravel_openframe_project's Issues

Missing pins in template def

The range gpio_loopback_zero[15:23] is missing in the template def file. In addition, some pins such as gpio_loopback_one[0] have two definitions. Each definition has a different location.

Hold violation on path with start point `gpio_in[38]` (clock)

Startpoint: gpio_in[38] (clock source 'clk')
Endpoint: _32086_ (rising edge-triggered flip-flop clocked by clk)
Path Group: clk
Path Type: min
Corner: Typical

Fanout     Cap    Slew   Delay    Time   Description
-----------------------------------------------------------------------------
                          0.00    0.00   clock clk (rise edge)
                          0.00    0.00   clock source latency
                  1.00    0.00    0.00 ^ gpio_in[38] (in)
     1    0.14                           gpio_in[38] (net)
                  1.11    0.05    0.05 ^ clkbuf_0_gpio_in[38]/A (sky130_fd_sc_hd__clkbuf_16)
                  0.13    0.35    0.40 ^ clkbuf_0_gpio_in[38]/X (sky130_fd_sc_hd__clkbuf_16)
     4    0.10                           clknet_0_gpio_in[38] (net)
                  0.13    0.01    0.41 ^ clkbuf_1_0__f_gpio_in[38]/A (sky130_fd_sc_hd__clkbuf_16)
                  0.16    0.23    0.64 ^ clkbuf_1_0__f_gpio_in[38]/X (sky130_fd_sc_hd__clkbuf_16)
     4    0.15                           clknet_1_0__leaf_gpio_in[38] (net)
                  0.16    0.01    0.65 ^ _26519_/B2 (sky130_fd_sc_hd__a22o_2)
                  0.03    0.14    0.79 ^ _26519_/X (sky130_fd_sc_hd__a22o_2)
     1    0.00                           _02974_ (net)
                  0.03    0.00    0.79 ^ _32086_/D (sky130_fd_sc_hd__dfxtp_1)
                                  0.79   data arrival time

                          0.00    0.00   clock clk (rise edge)
                          0.00    0.00   clock source latency
                  1.19    0.00    0.00 ^ gpio_in[38] (in)
     1    0.14                           gpio_in[38] (net)
                  1.30    0.06    0.06 ^ clkbuf_0_gpio_in[38]/A (sky130_fd_sc_hd__clkbuf_16)
                  0.14    0.41    0.47 ^ clkbuf_0_gpio_in[38]/X (sky130_fd_sc_hd__clkbuf_16)
     4    0.10                           clknet_0_gpio_in[38] (net)
                  0.14    0.01    0.48 ^ clkbuf_1_0__f_gpio_in[38]/A (sky130_fd_sc_hd__clkbuf_16)
                  0.16    0.25    0.73 ^ clkbuf_1_0__f_gpio_in[38]/X (sky130_fd_sc_hd__clkbuf_16)
     4    0.15                           clknet_1_0__leaf_gpio_in[38] (net)
                  0.18    0.04    0.77 ^ _15485_/A0 (sky130_fd_sc_hd__mux2_1)
                  0.05    0.17    0.94 ^ _15485_/X (sky130_fd_sc_hd__mux2_1)
     1    0.00                           _05023_ (net)
                  0.05    0.00    0.94 ^ _15486_/B (sky130_fd_sc_hd__and2b_2)
                  0.36    0.39    1.32 ^ _15486_/X (sky130_fd_sc_hd__and2b_2)
     2    0.07                           _05024_ (net)
                  0.36    0.02    1.34 ^ clkbuf_0__05024_/A (sky130_fd_sc_hd__clkbuf_16)
                  0.10    0.27    1.61 ^ clkbuf_0__05024_/X (sky130_fd_sc_hd__clkbuf_16)
     4    0.07                           clknet_0__05024_ (net)
                  0.10    0.01    1.62 ^ clkbuf_1_0__f__05024_/A (sky130_fd_sc_hd__clkbuf_16)
                  0.19    0.26    1.88 ^ clkbuf_1_0__f__05024_/X (sky130_fd_sc_hd__clkbuf_16)
    18    0.18                           clknet_1_0__leaf__05024_ (net)
                  0.19    0.01    1.89 ^ _15487_/B1 (sky130_fd_sc_hd__a21oi_2)
                  0.30    0.30    2.19 v _15487_/Y (sky130_fd_sc_hd__a21oi_2)
     2    0.14                           _00144_ (net)
                  0.30    0.02    2.21 v clkbuf_0__00144_/A (sky130_fd_sc_hd__clkbuf_16)
                  0.09    0.33    2.54 v clkbuf_0__00144_/X (sky130_fd_sc_hd__clkbuf_16)
     4    0.11                           clknet_0__00144_ (net)
                  0.09    0.00    2.54 v clkbuf_1_0_0__00144_/A (sky130_fd_sc_hd__clkbuf_8)
                  0.11    0.23    2.77 v clkbuf_1_0_0__00144_/X (sky130_fd_sc_hd__clkbuf_8)
     4    0.10                           clknet_1_0_0__00144_ (net)
                  0.11    0.00    2.78 v clkbuf_2_0_0__00144_/A (sky130_fd_sc_hd__clkbuf_8)
                  0.14    0.25    3.03 v clkbuf_2_0_0__00144_/X (sky130_fd_sc_hd__clkbuf_8)
     4    0.13                           clknet_2_0_0__00144_ (net)
                  0.16    0.04    3.07 v clkbuf_3_0_0__00144_/A (sky130_fd_sc_hd__clkbuf_8)
                  0.11    0.26    3.33 v clkbuf_3_0_0__00144_/X (sky130_fd_sc_hd__clkbuf_8)
     8    0.09                           clknet_3_0_0__00144_ (net)
                  0.11    0.01    3.34 v clkbuf_5_0_0__00144_/A (sky130_fd_sc_hd__clkbuf_8)
                  0.05    0.20    3.53 v clkbuf_5_0_0__00144_/X (sky130_fd_sc_hd__clkbuf_8)
     4    0.03                           clknet_5_0_0__00144_ (net)
                  0.05    0.00    3.54 v clkbuf_6_0__f__00144_/A (sky130_fd_sc_hd__clkbuf_16)
                  0.12    0.24    3.78 v clkbuf_6_0__f__00144_/X (sky130_fd_sc_hd__clkbuf_16)
    26    0.18                           clknet_6_0__leaf__00144_ (net)
                  0.12    0.01    3.78 v clkbuf_leaf_795__00144_/A (sky130_fd_sc_hd__clkbuf_16)
                  0.05    0.20    3.99 v clkbuf_leaf_795__00144_/X (sky130_fd_sc_hd__clkbuf_16)
     6    0.04                           clknet_leaf_795__00144_ (net)
                  0.05    0.00    3.99 v _1636_1645/A (sky130_fd_sc_hd__inv_2)
                  0.02    0.04    4.03 ^ _1636_1645/Y (sky130_fd_sc_hd__inv_2)
     1    0.00                           net5674 (net)
                  0.02    0.00    4.03 ^ _32086_/CLK (sky130_fd_sc_hd__dfxtp_1)
                          0.10    4.13   clock uncertainty
                          0.00    4.13   clock reconvergence pessimism
                         -0.03    4.10   library hold time
                                  4.10   data required time
-----------------------------------------------------------------------------
                                  4.10   data required time
                                 -0.79   data arrival time
-----------------------------------------------------------------------------
                                 -3.30   slack (VIOLATED)

The reason for opening this issue is that the start point and the clock triggering this path have the same source gpio_in[38] (clk) which is a bit odd. This only appeared after #5

RTL changes needed for iverilog v12

In the latest release of Iverilog, version 12.0.0, a new error has been introduced that detects mixing between old and new declaration module styles within RTL code. like the declaration here the compile resulted in the following error:

/home/rady/caravel/openframe/caravel_openframe_project//verilog/rtl/simple_spi_master.v:187: error: 'err_out' has already been declared in this scope.

Explanation of the issue is well defined in this comment by dave_59.

I will add the required RTL need.

changing spi master mode gives wrong value

When changing the spi master mode from 0 to 1 the written data at sdo is faster 1 cycle the the sck.
Here is a waveform of writing 0x1 when mode is 1(reading at negative edge )
image
This is read as 0x3

The waveform when writing 0x1 when mode is 0 (reading at posedge)
image

Need reset synchronization

The openframe project fails one testbench where the CPU fails to start up after bringing the chip out of SPI reset. Both the RESETB pin and the SPI reset need to be synchronized to the core clock.

Since the housekeeping SPI resets only on the POR signal, then there is no problem simply synchronizing the core reset to the core clock. The implementation should allow the reset to be set at any time, but the reset should only be released in synchronization with the clock (on the falling edge, to give a clock half-cycle time between reset release and the next clock positive edge).

The implementation should be: all_resetb = (RESETB pin & SPI resetb) ; core_resetb = (all_resetb & all_resetb_sync) where all_resetb_sync is all_resetb passed through two flops clocked by the inverse of the core clock, and reset to zero on porb.

Needs multiple power supply connections

The example needs to demonstrate how to connect multiple supply domains together to boost the current capacity of the supply feeding the user wrapper circuit and to minimize I-R drop across the user wrapper circuit. This example project should connect together the vccd, vccd1, and vccd2 domains into a single power supply.

How to chain the 2 timers?

I tried to add test for chaining the 2 timers but I can't figure out the right configuration for the registers.

Flashing isn't working with vcs

Cocotb tests are only working with iverilog and flashing fails with VCS. After debugging I found the problem are with the ack and stb signals and that lead me to these 2 warnings

Warning-[AOUP] Attempt to override undefined parameter
/home/rady/caravel/openframe/caravel_openframe_user_project//verilog/rtl/picosoc.v, 736
Attempting to override undefined parameter "ADR_MASK", will ignore it.

Warning-[AOUP] Attempt to override undefined parameter
/home/rady/caravel/openframe/caravel_openframe_user_project//verilog/rtl/picosoc.v, 736
Attempting to override undefined parameter "IFACE_ADR", will ignore it.

I'm not sure why this works with iverilog.
I fixed that at commit can you take a look?

master spi interrupt behaviour

The current interrupt in the spi master is triggered once the interrupt is enabled. Since the condition dependent on the done signal and the done signal is asserted most of the time.

If the correct behaviour is to send interrupt after each byte write, I suggest we might add the following:

reg done_delayed; 

always @(posedge clk) 
   done_delayed <= done; 
   
assign  irq_out = irqena & done & ~done_delayed;

counter interrupts

There are 2 problems with counter interrupts.

  1. The counter will continuously send interrupts after the count is finished. because of this condition as long as irq_ena is 1 and stop_out is 1 (happened when the counter finish couting)

This can be fixed by trigger interrupts only at the positive edge of stop_out

  1. It's not interrupt bug but it appears while debugging interrupt. Register value_reset isn't updated with the write condition I believe it should depend on the reg_dat_we rather than reg_val_we like this part of the code

This can be fixed by replacing reg_val_we with reg_dat_we in lines 174 to 177

Select out of bounds on signal `gpio_dat_o[*]`

In the following section, in picorv32.v:

	for (i = 0; i < 32; i = i + 1) begin
	    assign gpio_all_dat_o[i] = |(gpio_dat_o[i][`OPENFRAME_IO_PADS-1:0]);
	end

[`OPENFRAME_IO_PADS-1:0] is out of bound for the 32 bus gpio_data_o[i]. I believe the intention behind the for loop was to OR all i'th bit of each PADS gpio bus. The current for loop doesn't accomplish that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.