# SOC Spring Lab 4-0: report
## 1. spiflash access & code execution (observe CPU trace )
### i. Show waveform with related signals.

### ii. Correspond the waveform with the firmware code and testbench code.
```=
@00000000
6F 00 00 0B 13 00 00 00 13 00 00 00 13 00 00 00
13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
23 2E 11 FE 23 2C 51 FE 23 2A 61 FE 23 28 71 FE
```
Observe the firmware code, we can found the machine code of first instruction is `0B 00 00 6F`.
The caravel soc will fetch the instruction in the `spi-flash` from the lower address to higher address.
The first 8-bit fetch from spi-flash will be `8'h6F = 8'b0110_1111`. You can observe the `io1(SPI MISO)` signal to find the corresponding waveform. From `spi_addr = 0004~0007` the caravel fetch `6F 00 00 0B` from spi-flash.
After the instruction fetch from `spi-flash`, the instruction will go through `CPU iBus` as following waveform.

>instruction fetch `0B 00 00 6F` in iBus.
## 2. cpu wb cycles interaction with user project area.
### i. Show waveform with related signals.

### ii. Correspond the waveform with the firmware code and testbench code.
Refer to the waveform, it execute nine instruction as following:
```assembly=
#machine code|instruction |explanation
0x02C78793 addi a5, a5, 44 #get address
0x0007A703 lw a4, 0(a5) #a4 = a5 = reg_la0_data_in
0x1F400793 addi a5, zero, 500 #a5 = 500
0xFEE7F8E3 bgeu a5, a4, -2 #if (500 >= reg_la0_data_in)
0x260007B7 lui a5, 0x26000 #a5 = 0x26000_500
0x00C78793 addi a5, a5, 12 #a5 = 0x26000_00C
0xAB410737 lui a4, 0xAB410 #a4 = 0xAB410000
0x00E7A023 sw a4, 0(a5) #a5 = a4
0x00000013 addi x0, x0, 0 #nop
```
## 3. cpu interface with user project with la
### i. Show waveform with related signals.

### ii. Correspond the waveform with the firmware code and testbench code.
From `user_proj_example.counter.v`, we can found that when `la_write == 1(la_oenb[63:32] == 32'hFFFF_FFFF)`, `count` is written by `la_data_in[63:32]`.
#### user_proj_example.counter.v
```verilog=
//...order code
assign valid = wbs_cyc_i && wbs_stb_i;
assign wstrb = wbs_sel_i & {4{wbs_we_i}};
assign wbs_dat_o = rdata;
assign wdata = wbs_dat_i;
// IO
assign io_out = count;
assign io_oeb = {(`MPRJ_IO_PADS-1){rst}};
// IRQ
assign irq = 3'b000; // Unused
// LA
assign la_data_out = {{(127-BITS){1'b0}}, count};
// Assuming LA probes [63:32] are for controlling the count register
assign la_write = ~la_oenb[63:32] & ~{BITS{valid}};
// Assuming LA probes [65:64] are for controlling the count clk & reset
assign clk = (~la_oenb[64]) ? la_data_in[64]: wb_clk_i;
assign rst = (~la_oenb[65]) ? la_data_in[65]: wb_rst_i;
counter #(
.BITS(BITS)
) counter(
.clk(clk),
.reset(rst),
.ready(wbs_ack_o),
.valid(valid),
.rdata(rdata),
.wdata(wbs_dat_i),
.wstrb(wstrb),
.la_write(la_write),
.la_input(la_data_in[63:32]), //view the counter_la.c(firmware) define la[63:32] as output from CPU
.count(count)
);
endmodule
module counter #(
parameter BITS = 32
)(
input clk,
input reset,
input valid,
input [3:0] wstrb,
input [BITS-1:0] wdata,
input [BITS-1:0] la_write,
input [BITS-1:0] la_input,
output reg ready,
output reg [BITS-1:0] rdata,
output reg [BITS-1:0] count
);
//reg ready;
//reg [BITS-1:0] count;
//reg [BITS-1:0] rdata;
always @(posedge clk) begin
if (reset) begin
count <= 0;
ready <= 0;
end else begin
ready <= 1'b0;
if (~|la_write) begin
count <= count + 1;
end
if (valid && !ready) begin
ready <= 1'b1;
rdata <= count;
if (wstrb[0]) count[7:0] <= wdata[7:0];
if (wstrb[1]) count[15:8] <= wdata[15:8];
if (wstrb[2]) count[23:16] <= wdata[23:16];
if (wstrb[3]) count[31:24] <= wdata[31:24];
end else if (|la_write) begin
count <= la_write & la_input;
end
end
end
endmodule
`default_nettype wire
```
## 4. User project/RISC-V uses mprj pin, and interacts with Testbench
### i. Show waveform with related signals.

### ii. Correspond the waveform with the firmware code and testbench code.
The `mprj_io[31:16]` pins is program by CPU. CPU program these GPIO through `dBus(Wishbone Bus)`, as shown in firmware code.
How would CPU program `mprj` depends on the value of counter `count`. It would transmit to CPU throgh `Logic analyzer(reg_la0_data_in)`.
The value of these `mpjr` pins will determine the flow testbench.
#### counter_la.c(firmware)
```c=
// This include is relative to $CARAVEL_PATH (see Makefile)
#include <defs.h>
#include <stub.c>
// --------------------------------------------------------
/*
MPRJ Logic Analyzer Test:
- Observes counter value through LA probes [31:0]
- Sets counter initial value through LA probes [63:32]
- Flags when counter value exceeds 500 through the management SoC gpio
- Outputs message to the UART when the test concludes successfuly
*/
void main()
{
int j;
//Set mprj pin to management soc
reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT;
reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT;
//Set mprj pin to User project area
reg_mprj_io_15 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_14 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_13 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_12 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_11 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_10 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_9 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_8 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_7 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_5 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_4 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_3 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_2 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_1 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_0 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT;
// Set UART clock to 64 kbaud (enable before I/O configuration)
// reg_uart_clkdiv = 625;
reg_uart_enable = 1;
// Now, apply the configuration
reg_mprj_xfer = 1;
while (reg_mprj_xfer == 1);
// Configure LA probes [31:0], [127:64] as inputs to the cpu
// Configure LA probes [63:32] as outputs from the cpu
reg_la0_oenb = reg_la0_iena = 0x00000000; // [31:0]
reg_la1_oenb = reg_la1_iena = 0xFFFFFFFF; // [63:32]
reg_la2_oenb = reg_la2_iena = 0x00000000; // [95:64]
reg_la3_oenb = reg_la3_iena = 0x00000000; // [127:96]
// Flag start of the test
reg_mprj_datal = 0xAB400000;
// Set Counter value to zero through LA probes [63:32]
reg_la1_data = 0x00000000;
// Configure LA probes from [63:32] as inputs to disable counter write
reg_la1_oenb = reg_la1_iena = 0x00000000;
while (1) {
if (reg_la0_data_in > 0x1F4) {
reg_mprj_datal = 0xAB410000;
break;
}
}
//print("\n");
//print("Monitor: Test 1 Passed\n\n"); // Makes simulation very long!
reg_mprj_datal = 0xAB510000;
}
```
```c=
#define reg_mprj_datal (*(volatile uint32_t*)0x2600000c)
#define reg_mprj_datah (*(volatile uint32_t*)0x26000010)
```
>caravel.h
`reg_mprj_datal` used to write `mprj_io[31:0]`.
`reg_mprj_datah` used to write `mprj_io[37:32]`.
so that these `mprj_io` pin have value.
```c=
#define reg_la3_data_in (*(volatile uint32_t*) CSR_LA_IN_ADDR)
#define reg_la2_data_in (*(volatile uint32_t*) (CSR_LA_IN_ADDR + 4))
#define reg_la1_data_in (*(volatile uint32_t*) (CSR_LA_IN_ADDR + 8))
#define reg_la0_data_in (*(volatile uint32_t*) (CSR_LA_IN_ADDR + 12))
```
>firmware/defs.h
>There is four 32-bit MMIO register, corresponding to 128-bit input of LA.
>**Question:** It seems unclear how the logic analyzer (LA) is connected to the counter—I couldn’t find the definition?
```verilog=
//...order code
initial begin
wait(checkbits == 16'hAB40);
$display("LA Test 1 started");
wait(checkbits == 16'hAB41);
wait(checkbits == 16'hAB51);
$display("LA Test 2 passed");
#10000;
$finish;
end
```
>tb.v
>The value of `mprj[31:16] = checkbits` will affect testbench execution flow.