Merge pull request #12 from wallento/master

Documentation improvements
This commit is contained in:
Pasquale Davide Schiavone 2018-11-26 10:11:13 +01:00 committed by GitHub
commit b1b89f55fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 261 additions and 47 deletions

View file

@ -32,7 +32,8 @@ numfig_format = {'figure': 'Figure %s', 'table': 'Table %s', 'code-block': 'List
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
extensions = ['sphinxcontrib.wavedrom']
wavedrom_html_jsinline = False
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

View file

@ -88,6 +88,8 @@ Reset Value: ``0x0000_0000``
+-------+-----+------------------------------------------------------------------+
.. _csr-mhartid:
MHARTID
-------

View file

@ -1,13 +0,0 @@
{signal: [
{name: 'clk', wave: 'p......'},
{name: 'data_addr_o', wave: 'x=.xxxx', data: ['Address']},
{name: 'data_wdata_o', wave: 'x=.xxxx', data: ['WData']},
{name: 'data_req_o', wave: '01.0...'},
{name: 'data_gnt_i', wave: '0.10...'},
{name: 'data_rvalid_i', wave: '0..10..'},
{name: 'data_wdata_o', wave: 'xxx=xxx', data: ['RData']},
{name: 'data_we_o', wave: 'x=.xxxx', data: ['WE']},
{name: 'data_be_o', wave: 'x=.xxxx', data: ['BE']},
],
config: { hscale: 2 }
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View file

@ -1,13 +0,0 @@
{signal: [
{name: 'clk', wave: 'p......'},
{name: 'data_addr_o', wave: 'x==xxxx', data: ['Addr1', 'Addr2']},
{name: 'data_wdata_o', wave: 'x==xxxx', data: ['WData1', 'Wdata2']},
{name: 'data_req_o', wave: '01.0...'},
{name: 'data_gnt_i', wave: '01.0...'},
{name: 'data_rvalid_i', wave: '0.1.0..'},
{name: 'data_wdata_o', wave: 'xx==xxx', data: ['RData1', 'RData2']},
{name: 'data_we_o', wave: 'x==xxxx', data: ['WE1', 'WE2']},
{name: 'data_be_o', wave: 'x==xxxx', data: ['BE1', 'BE2']},
],
config: { hscale: 2 }
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View file

@ -1,13 +0,0 @@
{signal: [
{name: 'clk', wave: 'p......'},
{name: 'data_addr_o', wave: 'x=..xxx', data: ['Address']},
{name: 'data_wdata_o', wave: 'x=..xxx', data: ['WData']},
{name: 'data_req_o', wave: '01..0..'},
{name: 'data_gnt_i', wave: '0..10..'},
{name: 'data_rvalid_i', wave: '0....10'},
{name: 'data_wdata_o', wave: 'xxxxx=x', data: ['RData']},
{name: 'data_we_o', wave: 'x=..xxx', data: ['WE']},
{name: 'data_be_o', wave: 'x=..xxx', data: ['BE']},
],
config: { hscale: 2 }
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View file

@ -11,10 +11,12 @@ ZERO-RISCY: User Manual
:caption: Contents:
introduction
integration
instruction_fetch
load_store_unit
register_file
cs_registers
interrupts
performance_counters
exception_interrupts
debug

View file

@ -35,3 +35,27 @@ Protocol
--------
The protocol used to communicate with the instruction cache or the instruction memory is the same as the protocol used by the LSU. See the description of the LSU in :ref:`LSU Protocol<lsu-protocol>` for details about the protocol.
.. caution::
The instruction fetch interface differs from the LSU interface in that the address can change
while the request is valid. This is because it can update the instructions to fetch when a
branch occurs. As depicted in :numref:`if_timing_difference` care has to be taken when
working with the address. The data returned must of course match the address during the grant
cycle.
.. wavedrom::
:name: if_timing_difference
:caption: Memory transaction with wait states
{"signal":
[
{"name": "clk", "wave": "p......"},
{"name": "data_addr_o", "wave": "x===xxx", "data": ["Address", "Address", "Address"]},
{"name": "data_req_o", "wave": "01..0.."},
{"name": "data_gnt_i", "wave": "0..10.."},
{"name": "data_rvalid_i", "wave": "0....10"},
{"name": "data_rdata_i", "wave": "xxxxx=x", "data": ["RData"]}
],
"config": { "hscale": 2 }
}

121
doc/integration.rst Normal file
View file

@ -0,0 +1,121 @@
Core Integration
================
The main module is named ``zeroriscy_core`` and can be found in ``zeroriscy_core.sv``. In the following the instantiation template is given and the parameters and interfaces are described.
Instantiation Template
----------------------
.. code-block:: verilog
zeroriscy_core
#(.N_EXT_PERF_COUNTERS (0),
.RV32E (0),
.RV32M (1))
u_core
(// Clock and reset
.clk_i (),
.rst_ni (),
.clock_en_i (),
.test_en_i (),
// Configuration
.core_id_i (),
.cluster_id_i (),
.boot_addr_i (),
// Instruction memory interface
.instr_req_o (),
.instr_gnt_i (),
.instr_rvalid_i (),
.instr_addr_o (),
.instr_rdata_i (),
// Data memory interface
.data_req_o (),
.data_gnt_i (),
.data_rvalid_i (),
.data_we_o (),
.data_be_o (),
.data_addr_o (),
.data_wdata_o (),
.data_rdata_i (),
.data_err_i (),
// Interrupt inputs
.irq_i (),
.irq_id_i (),
.irq_ack_o (),
.irq_id_o (),
// Debug Interface
.debug_req_i (),
.debug_gnt_o (),
.debug_rvalid_o (),
.debug_addr_i (),
.debug_we_i (),
.debug_wdata_i (),
.debug_rdata_o (),
.debug_halted_o (),
.debug_halt_i (),
.debug_resume_i (),
// Special control signal
.fetch_enable_i (),
// External performance counters
.ext_perf_counters_i ()
);
Parameters
----------
+-------------------------+-------------+---------+------------------------------------------------+
| Name | Type/Range | Default | Description |
+=========================+=============+=========+================================================+
| ``N_EXT_PERF_COUNTERS`` | int (0..21) | 0 | Number of external performance counters |
+-------------------------+-------------+---------+------------------------------------------------+
| ``RV32E`` | int (0..1) | 0 | RV32E mode enable (16 integer registers only) |
+-------------------------+-------------+---------+------------------------------------------------+
| ``RV32M`` | int (0..1) | 1 | M(ultiply) extension enable |
+-------------------------+-------------+---------+------------------------------------------------+
Interfaces
----------
+-------------------------+-------------------------+-----+----------------------------------------+
| Signal(s) | Width | Dir | Description |
+=========================+=========================+=====+========================================+
| ``clk_i`` | 1 | in | Clock signal |
+-------------------------+-------------------------+-----+----------------------------------------+
| ``rst_ni`` | 1 | in |Active-low synchronous reset |
+-------------------------+-------------------------+-----+----------------------------------------+
| ``clock_en_i`` | 1 | in | Clock gating input |
| | | | (0: clock gated, 1: clock running) |
+-------------------------+-------------------------+-----+----------------------------------------+
| ``test_en_i`` | 1 | in | Test input, enables clock |
+-------------------------+-------------------------+-----+----------------------------------------+
| ``core_id_i`` | 4 | in | Core id, usually static, can be read |
| | | | from :ref:`csr-mhartid` |
+-------------------------+-------------------------+-----+ +
| ``cluster_id_i`` | 6 | in | |
+-------------------------+-------------------------+-----+----------------------------------------+
| ``boot_adr_i`` | 32 | in | First program counter after reset |
+-------------------------+-------------------------+-----+----------------------------------------+
| ``instr_*`` | Instruction fetch interface, see :ref:`instruction-fetch` |
+-------------------------+------------------------------------------------------------------------+
| ``data_*`` | Load-store unit interface, see :ref:`load-store-unit` |
+-------------------------+------------------------------------------------------------------------+
| ``irq_*`` | Interrupt interface, see :ref:`interrupts` |
+-------------------------+------------------------------------------------------------------------+
| ``debug_*`` | Debug interface, see :ref:`debug-unit` |
+-------------------------+-------------------------+-----+----------------------------------------+
| ``fetch_enable_i`` | 1 | in | Enable the core, won't fetch when 0 |
+-------------------------+-------------------------+-----+----------------------------------------+
| ``ext_perf_counters_i`` | ``N_EXT_PERF_COUNTERS`` | in | External performance counter |
+-------------------------+-------------------------+-----+----------------------------------------+

56
doc/interrupts.rst Normal file
View file

@ -0,0 +1,56 @@
.. _interrupts:
Interrupts
==========
Interrupts are signaled via the external core interface:
+-------------------------+-----------+-----------------------------------------------+
| Signal | Direction | Description |
+=========================+===========+===============================================+
| ``irq_i`` | in | Interrupt event, level sensitive |
+-------------------------+-----------+-----------------------------------------------+
| ``irq_id_i[4:0]`` | in | Interrupt ID |
+-------------------------+-----------+-----------------------------------------------+
| ``irq_ack_o`` | out | Interrupt acknowledgement |
+-------------------------+-----------+-----------------------------------------------+
| ``irq_id_o[4:0]`` | out | Interrupt acknowledgement ID |
+-------------------------+-----------+-----------------------------------------------+
When external interrupts are enabled, the core will serve interrupt requests. An interrupt is signaled as asserted high level at the ``irq_i`` signal. The interrupt ID determines the interrupt vector ID (0 to 31).
Once the interrupt processing is completed, the core will assert ``irq_ack_o`` for one clock cycle along with the identifier that has been completed.
.. important::
The core may not start interrupt processing in the same cycle the level changes.
:numref:`irq-processing` shows the signal timing during a standard interrupt cycle.
.. wavedrom::
:name: irq-processing
:caption: Interrupt processing
{ "signal": [
{ "name": "clk_i", "wave": "p...", "period": 2 },
{ "name": "irq_i", "wave": "01..|.0." },
{ "name": "irq_id_i", "wave": "x=..|.x.", "data": ["ID0"] },
{ "name": "irq_ack_o", "wave": "0...|10." },
{ "name": "irq_id_id", "wave": "x...|=x.", "data": ["ID0"] }
]
}
As the interrupt identifier is registered once it is handled, it is allowed that the interrupt identifier at the input changes. This behavior can be used to handle interrupt priorities. But as the core may already have started interrupt processing, it is necessary to check the acknowledged ID. An example cycle is shown in :numref:`irq-processing-prio`.
.. wavedrom::
:name: irq-processing-prio
:caption: Typical interrupt processing with priorization on the interface. Here the processing of ``ID0`` has already started.
{ "signal": [
{ "name": "clk_i", "wave": "p...", "period": 2 },
{ "name": "irq_i", "wave": "01..|.1." },
{ "name": "irq_id_i", "wave": "x=.=|...", "data": ["ID0", "ID1"] },
{ "name": "irq_ack_o", "wave": "0...|10." },
{ "name": "irq_id_id", "wave": "x...|=x.", "data": ["ID0"] }
]
}

View file

@ -51,17 +51,63 @@ The LSU provides a valid address in ``data_addr_o`` and sets ``data_req_o`` high
:numref:`timing1`, :numref:`timing2` and :numref:`timing3` show example-timing diagrams of the protocol.
.. figure:: images/timing1.png
.. wavedrom::
:name: timing1
:caption: Basic Memory Transaction
Basic Memory Transaction
{"signal":
[
{"name": "clk", "wave": "p......"},
{"name": "data_addr_o", "wave": "x=.xxxx", "data": ["Address"]},
{"name": "data_wdata_o", "wave": "x=.xxxx", "data": ["WData"]},
{"name": "data_req_o", "wave": "01.0..."},
{"name": "data_gnt_i", "wave": "0.10..."},
{"name": "data_rvalid_i", "wave": "0..10.."},
{"name": "data_wdata_o", "wave": "xxx=xxx", "data": ["RData"]},
{"name": "data_we_o", "wave": "x=.xxxx", "data": ["WE"]},
{"name": "data_be_o", "wave": "x=.xxxx", "data": ["BE"]}
],
"config": { "hscale": 2 }
}
.. figure:: images/timing2.png
.. wavedrom::
:name: timing2
:caption: Back-to-back Memory Transaction
Back-to-back Memory Transaction
{"signal":
[
{"name": "clk", "wave": "p......"},
{"name": "data_addr_o", "wave": "x==xxxx", "data": ["Addr1", "Addr2"]},
{"name": "data_wdata_o", "wave": "x==xxxx", "data": ["WData1", "Wdata2"]},
{"name": "data_req_o", "wave": "01.0..."},
{"name": "data_gnt_i", "wave": "01.0..."},
{"name": "data_rvalid_i", "wave": "0.1.0.."},
{"name": "data_wdata_o", "wave": "xx==xxx", "data": ["RData1", "RData2"]},
{"name": "data_we_o", "wave": "x==xxxx", "data": ["WE1", "WE2"]},
{"name": "data_be_o", "wave": "x==xxxx", "data": ["BE1", "BE2"]}
],
"config": { "hscale": 2 }
}
.. figure:: images/timing3.png
.. wavedrom::
:name: timing3
:caption: Slow Response Memory Transaction
{"signal":
[
{"name": "clk", "wave": "p......"},
{"name": "data_addr_o", "wave": "x=..xxx", "data": ["Address"]},
{"name": "data_wdata_o", "wave": "x=..xxx", "data": ["WData"]},
{"name": "data_req_o", "wave": "01..0.."},
{"name": "data_gnt_i", "wave": "0..10.."},
{"name": "data_rvalid_i", "wave": "0....10"},
{"name": "data_wdata_o", "wave": "xxxxx=x", "data": ["RData"]},
{"name": "data_we_o", "wave": "x=..xxx", "data": ["WE"]},
{"name": "data_be_o", "wave": "x=..xxx", "data": ["BE"]}
],
"config": { "hscale": 2 }
}
Slow Response Memory Transaction

View file

@ -1,3 +1,4 @@
setuptools_scm
sphinx
sphinx>=1.8
sphinx_rtd_theme
git+https://github.com/wallento/sphinx-wavedrom