Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs/LPC_Additional_LPC_Cycles.md: document added #36

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2384f25
docs/LPC_Additional_LPC_Cycles.md: document added
mgabryelski1 Sep 2, 2022
ae7c58e
docs/LPC_Additional_LPC_Cycles.md: finished
mgabryelski1 Sep 4, 2022
77e430a
docs/LPC_Additional_LPC_Cycles.md : documentation related to skipping…
mgabryelski1 Sep 7, 2022
62ffc43
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
22259ed
Update docs/LPC_Additional_LFix #2PC_Cycles.md
mgabryelski1 Oct 4, 2022
deea0ab
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
7fd904b
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
6bdd2d9
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
fcae1e1
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
e96ac71
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
2bda8dc
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
4fb8772
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
f3397ea
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
eb8b916
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
faaa4d5
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
162dfbf
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
d02a4c0
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
8d695da
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
4a26eb0
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
012b0bb
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
2bda440
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
5fedeeb
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
fee82d4
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
f553ff4
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
edc4f53
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
32ab633
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
4a1bc88
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
bed90b9
Update docs/LPC_Additional_LPC_Cycles.md
mgabryelski1 Oct 4, 2022
074efd1
docs/LPC_Additional_LPC_Cycles.md: rendering fixes
mgabryelski1 Oct 4, 2022
fafc3c1
docs/LPC_Additional_LPC_Cycles.md: sim tool name updted
mgabryelski1 Oct 4, 2022
899ddc9
docs/LPC_Additional_LPC_Cycles.md: code block fix
mgabryelski1 Oct 4, 2022
06e784e
docs/LPC_Additional_LPC_Cycles.md: fix rendering, style and typos, up…
arturkow2000 Oct 6, 2022
550be85
Changes related to handling TPM cycles
mgabryelski1 Oct 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 248 additions & 0 deletions docs/LPC_Additional_LPC_Cycles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
## Why do we need to support additional LPC protocol cycles in "LPC Host"

In the implementation of the LPC (LPC Host and LPC Peripheral) protocol we wrote
earlier, only two types of LPC cycles were supported:
+ I / O cycles (Read and Write)
arturkow2000 marked this conversation as resolved.
Show resolved Hide resolved
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
+ TPM cycles
Copy link

@arturkow2000 arturkow2000 Sep 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TPM cycles actually are not supported - those are basically the same as I/O cycles but have a different START field. Peripheral checks START == b0000` before transitioning from IDLE to START.
Please also see this comment #36 (comment)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mgabryelski1 This is not fixed, we can't claim we support TPM cycles when actually we don't

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These issues were corrected by me.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mgabryelski1 This is still not fixed, until lpn-plant/lpntpm-lpc-verilog#3 came there was no support for TPM cycles.


And we really do not need to support more types of LPC cycles in the designed
arturkow2000 marked this conversation as resolved.
Show resolved Hide resolved
TPM module, but there is a need to check how the "LPC peripheral" module we wrote
reacts to other types of cycles appearing on the 4-bit LAD bus. For this purpose,
it was necessary to extend the "LPC Host" implementation with additional LPC protocol
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
cycle types.

The "LPC peripheral" module should record all the occurrences on the LAD of the
`I/O` and `TPM` cycles and send their data (LPC address and LPC data) to the
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
MCU module of SoC (by 32-bit output bus in FPGA). However, other LPC protocol cycle
types on the LAD bus should be ignored and their data should not be logged.

It is enough to add one additional type of supported cycles to the `LPC Host`
module as the response of the "LPC Peripheral" to all additional cycle types
should be similar. The choice fell on `Memory Read/Write` cycles because they are
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
quite similar to `I/O` cycles and easy to implement.

## Changes related to the addition of "Memory" cycles support in "LPC Host"

First, let's look at the similarities and differences between the `I/O` and `Memory`
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
cycles.For this purpose we will look at Intel's `LPC Protocol` reference document.
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
See screen shots from this document. First we have description of `I/O` cycles
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
![LPC IO Cycles](images/I_O_LPC_Cycles.png)

The most important here are the `START` and `CYCTYPE` fields:

+ START has value: 0000b
+ CYCTYPE has values: 0000b or 0010b
And we also see that whole `I/O`c cycle has a length of 13 clock cycles.
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved

Second we have description of `Memory R/W` cycles:
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
![LPC Memory cycles](images/LPC_Memory_Cycles_c1.png)

![LPC Memory cycles](images/LPC_Memory_cycles_c2.png)

The most important here are also the `START` and `CYCTYPE` fields:

+ START has value: 0000b
+ CYCTYPE has values: 0100b or 0110b
And we also see that whole `Memory R/W`c cycle has a length of 21(read) or 17(write)
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
clock cycles. The field Address on LAD bus is longer compared to `I/O` cycles.

## Changes in the "LPC Host" implementation regarding the handling of `Memory R/W` cycles

1. First, we added the *ctrl_memory_cycle_i* input signal to the `lpc_host` port
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
list - see in code:
```verilog

`include "lpc_defines.v"

module lpc_host (clk_i, ctrl_addr_i, ctrl_data_i, ctrl_nrst_i, ctrl_lframe_i,
ctrl_rd_status_i, ctrl_wr_status_i, ctrl_memory_cycle_i,
ctrl_data_o, ctrl_ready_o, ctrl_host_state_o,
LPC_LAD, LPC_LCLK, LPC_LRESET, LPC_LFRAME
);

input wire clk_i;

// Control signals are used to drive the control the LPC host.
// Control signals (input)
input wire [15:0] ctrl_addr_i;
input wire [ 7:0] ctrl_data_i;
input wire ctrl_nrst_i;
input wire ctrl_lframe_i;
input wire ctrl_rd_status_i;
input wire ctrl_wr_status_i;
input wire ctrl_memory_cycle_i; // 1- means Memory cycle, 0 - means I/O cycle

// Control signals (output)
output reg [ 7:0] ctrl_data_o;
output reg ctrl_ready_o;
output wire [ 4:0] ctrl_host_state_o;

// LPC Host Interface
inout wire [ 3:0] LPC_LAD;
output wire LPC_LCLK;
output reg LPC_LRESET;
output reg LPC_LFRAME;
```
2. Secondly, in the `LPC_ST_START` phase of the LPC cycle (FSM machine), depending
on the state of the `ctrl_memory_cycle_i` input (high state means Memory cycle),
we changed the value of the CYCTYPE field on the LAD bus to the one appropriate
for the `Memory`cycle - see code:
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
arturkow2000 marked this conversation as resolved.
Show resolved Hide resolved

```verilog
else if (fsm_host_state == `LPC_ST_START) begin
if (~ctrl_memory_cycle_i) begin
if (ctrl_lframe_i & ctrl_rd_status_i) begin
LPC_LFRAME = 1;
lad_out = 4'b0000;
fsm_host_state = `LPC_ST_CYCTYPE_RD;
end
else if (ctrl_lframe_i & ctrl_wr_status_i) begin
LPC_LFRAME = 1;
lad_out = 4'b0010;
fsm_host_state = `LPC_ST_CYCTYPE_WR;
end
end if (ctrl_memory_cycle_i) begin
if (ctrl_lframe_i & ctrl_rd_status_i) begin
LPC_LFRAME = 1;
lad_out = 4'b0100;
fsm_host_state = `LPC_ST_CYCTYPE_MEMORY_RD;
end
else if (ctrl_lframe_i & ctrl_wr_status_i) begin
LPC_LFRAME = 1;
lad_out = 4'b0110;
fsm_host_state = `LPC_ST_CYCTYPE_MEMORY_WR;
end
end
end
```
3. Third, changes in two places in the FSM code - starting the Memory cycles:
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved

```verilog
. . .
else if ((fsm_host_state == `LPC_ST_CYCTYPE_RD) || (fsm_host_state == `LPC_ST_CYCTYPE_MEMORY_RD)) begin

lad_out = ctrl_addr_i[15:12];
fsm_host_state = `LPC_ST_ADDR_RD_CLK1;
end
. . .
else if ((fsm_host_state == `LPC_ST_CYCTYPE_WR) || (fsm_host_state == `LPC_ST_CYCTYPE_MEMORY_WR)) begin
lad_out = ctrl_addr_i[15:12];
fsm_host_state = `LPC_ST_ADDR_WR_CLK1;
end
. . .
```

## Changes in the "LPC Peripheral" implementation regarding skipping of LPC cycles different than `I/O` or `TPM`

+ First, one internal signal has been added:

```verilog
reg skipCycle; // 1 -indicates that this cycle is not I/O or TPM cycle, 0 - indicates I/O or TPM cycle
```
+ On the main state machine (FSM) supporting LPC cycles - states `LPC_ST_IDLE`
arturkow2000 marked this conversation as resolved.
Show resolved Hide resolved
and` LPC_ST_START` were modified:

```verilog
case(current_state_o)
`LPC_ST_IDLE:
begin
skipCycle <= 1'b0;
if (nrst_i == 1'b0) fsm_next_state <= `LPC_ST_IDLE;
else if ((lframe_i == 1'b0) && (lad_bus == 4'h0)) fsm_next_state <= `LPC_ST_START;
end
`LPC_ST_START:
begin
if ((lframe_i == 1'b0) && (lad_bus == 4'h0)) fsm_next_state <= `LPC_ST_START;
else if ((lframe_i == 1'b1) && (lad_bus != 4'h0) && (lad_bus != 4'h2)) skipCycle = 1'b1;
else if ((lframe_i == 1'b1) && (lad_bus == 4'h0)) fsm_next_state <= `LPC_ST_CYCTYPE_RD;
else if ((lframe_i == 1'b1) && (lad_bus == 4'h2)) fsm_next_state <= `LPC_ST_CYCTYPE_WR;
end
```
When in the `LPC_ST_START` state, the LAD bus does not have a CYCTYPE meaning I / O`
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
arturkow2000 marked this conversation as resolved.
Show resolved Hide resolved
or `Memory` cycles, the `skipCycle` signal becomes High.
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved

+ In the rest of the code, the value of the `lpc_en_o` signal is worked out already
using the signal state of the` skipCycle`
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved

```verilog
assign lpc_en_o = ((!skipCycle)&&(sync_en == 1'b1)) ? 1'h1 :
((!skipCycle)&&(tar_F == 1'b1 )) ? 1'h1 :
(lframe_i == 1'b0 ) ? 1'h0 :
((!skipCycle)&&(rd_data_en[0] == 1'b1)) ? 1'b1 :
((!skipCycle)&&(rd_data_en[1] == 1'b1)) ? 1'b1 :
1'h0;
```
This causes LPC cycle data not to be recorded on the output bus for cycles other
than `I/O` and` TPM`.
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved

## Changes in the `test bench` implementation regarding the handling of `Memory R/W` cycles

+ In the test bench, firstly we added `memory_cycle_sig` to the list of internal
signals of the `lpc_periph_tb` module:

```verilog
reg [15:0] u_addr; //auxiliary host addres
reg [7:0] u_data; //auxiliary host data
integer i, j;
reg memory_cycle_sig;
```
+ Second, to the main loop sending the cycle data to module `lpc_host` we add
arturkow2000 marked this conversation as resolved.
Show resolved Hide resolved
second for loop for setting `memory_cycle_sig` signal value. In this way, the
`I/O` and `Memory` cycles are alternately sent:
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved

```verilog
for (i = 0; i <= 128; i = i + 1) begin
for(j = 0; j < 2; j = j + 1) begin
memory_cycle_sig = j; //Cycle type: Memory or I/O
// Perform write
#40 lframe_i = 0;
rd_flag = 0;
wr_flag = 1;
host_addr_i = u_addr+i;
host_wr_i = u_data+i;
#40 lframe_i = 1;
#400 lframe_i = 0;
. . .
```
## The results of the simulation of the `lpc-periph` module in Xilinx vivado 2019.1
arturkow2000 marked this conversation as resolved.
Show resolved Hide resolved

First, we will look at the simulation of the `lpc_periph` module for `I/O` cycles:
arturkow2000 marked this conversation as resolved.
Show resolved Hide resolved
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved

![LPC I/O cycles](images/Icarusverilog_SIM_01.png)

As you can see in the screenshot from `Icarus verilog` (simulation) - the value of
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
signal `memory_cycle_sig` is Low, meaning the `I/O` cycle. At the point marked
with a vertical (pink) line, the output bus signal `TDATABOu [31:0]` is changed
to the values sent by the `LPC Host` and the pulse (high state) of the `READYNET`
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
signal is generated (which means that there are new data on output bus). Also signal
`periph_en`(High) is generated. The states of the FSM machines for `LPC Host`
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
and `LPC Peripheral` are also important - you can see that here the FSM machine
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
states from peripheral mimics these from host. It means that, complete `I/O`
cycles are performed by `LPC Peripheral`.

In the second screenshot we can see what the signals for the `Memory` cycle look
like:
![LPC Memory cycles](images/Icarusverilog_SIM_02.png)

Signal `memory_cycle_sig` has High value this time. In the time slot marked with
a vertical (pink) line you can see that the `LPC Peripheral` do not generate
`periph_en`(High) signal. The state of the LAD bus is then 0x6 in CYCTYPE field
which means the `Memory` cycle. Because signal `periph_en` hadn't been generated
the cycle data sent by Host is not registered on output bus `TDATABOu [31:0]` nor
`READYNET` signal was generated. Such `LPC Peripheral` reaction is expected - in
this case during the execution of the `Memory` cycle registering cycle data is
skipped.

Now let's look at the third simulation screenshot:
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
![LPC I/O cycles](images/IcarusVerilog_SIM_03.png)


We can also observe on the last simulation screenshot that while the state of
mgabryelski1 marked this conversation as resolved.
Show resolved Hide resolved
the `memory_cycle_sig` signal is high (`Memory` cycle) there is never a change in the
state of the output bus `TDATABOu [31: 0]`. Signal `periph_en` (High) is also never
generated when `memory_cycle_sig` signal is high. Such behavior of `LPC Peripheral`
was expected before simulating the `LPC pripheral` operation - `I/O` cycles should
be recorded, other cycle types should be ignored.



Binary file added docs/images/I_O_Cycle_OutDataChanged.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/I_O_LPC_Cycles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/IcarusVerilog_SIM_03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/Icarusverilog_SIM_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/Icarusverilog_SIM_02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/LPC_Memory_Cycles_c1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/LPC_Memory_cycles_c2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/Memory_cycle_03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/Memory_cycles_SIM.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.