Line Coverage for Module :
spid_dpram
| Line No. | Total | Covered | Percent |
TOTAL | | 20 | 20 | 100.00 |
CONT_ASSIGN | 64 | 1 | 1 | 100.00 |
CONT_ASSIGN | 65 | 1 | 1 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
CONT_ASSIGN | 71 | 1 | 1 | 100.00 |
CONT_ASSIGN | 83 | 1 | 1 | 100.00 |
CONT_ASSIGN | 84 | 1 | 1 | 100.00 |
CONT_ASSIGN | 91 | 1 | 1 | 100.00 |
CONT_ASSIGN | 92 | 1 | 1 | 100.00 |
ALWAYS | 103 | 7 | 7 | 100.00 |
ALWAYS | 118 | 3 | 3 | 100.00 |
CONT_ASSIGN | 165 | 1 | 1 | 100.00 |
CONT_ASSIGN | 173 | 1 | 1 | 100.00 |
63 sram_addr_t sys2spi_wr_addr;
64 1/1 assign sys2spi_wr_req = (sys_addr_i < Sys2SpiEnd) & sys_req_i & sys_write_i;
Tests: T1 T2 T3
65 1/1 assign sys2spi_wr_addr = sys_addr_i - Sys2SpiOffset;
Tests: T1 T2 T3
66
67 // SPI reads from only the Sys2Spi memory.
68 logic sys2spi_rd_req;
69 sram_addr_t sys2spi_rd_addr;
70 1/1 assign sys2spi_rd_req = spi_req_i & !spi_write_i;
Tests: T1 T2 T3
71 1/1 assign sys2spi_rd_addr = spi_addr_i - Sys2SpiOffset;
Tests: T1 T2 T3
72
73 // SPI Wr, SYS Rd is for payload upload
74 localparam sram_addr_t Spi2SysOffset = SramIngressIdx;
75 localparam int unsigned Spi2SysMinDepth = SramPayloadDepth + SramCmdFifoDepth
76 + SramAddrFifoDepth + SramTpmWrFifoDepth;
77 localparam int unsigned Spi2SysAw = $clog2(Spi2SysMinDepth);
78 localparam int unsigned Spi2SysDepth = 1 << Spi2SysAw;
79
80 // SPI writes to only the Spi2Sys memory.
81 logic spi2sys_wr_req;
82 sram_addr_t spi2sys_wr_addr;
83 1/1 assign spi2sys_wr_req = spi_req_i & spi_write_i;
Tests: T1 T2 T3
84 1/1 assign spi2sys_wr_addr = spi_addr_i - Spi2SysOffset;
Tests: T1 T2 T3
85
86 // SYS reads only read from the Spi2Sys memory.
87 // Allow all reads to complete, so the bus always gets a response, even if
88 // software chooses to read from write-only addresses.
89 logic spi2sys_rd_req;
90 sram_addr_t spi2sys_rd_addr;
91 1/1 assign spi2sys_rd_req = sys_req_i & !sys_write_i;
Tests: T1 T2 T3
92 1/1 assign spi2sys_rd_addr = sys_addr_i - Spi2SysOffset;
Tests: T1 T2 T3
93
94 // The SPI -> core buffer for the payload uses parity and SW has no way of initializing it since
95 // the write port is in the SPI domain. Since the SPI side writes the payload byte by byte,
96 // we need to guard against partially initialized 32bit words, because these could cause TL-UL
97 // bus errors upon readout. Unfortunately, an initialization circuit that initializes the entire
98 // SRAM on the SPI clock domain is infeasible since that clock is only intermittently available.
99 // Hence, we keep track of uninitialized words using a valid bit array, and upon the first write
100 // to a word, uninitialized bytes are set to zero if the write operation is a sub-word write op.
101 logic [SramDw-1:0] spi_wdata, spi_wmask;
102 logic [Spi2SysDepth-1:0] initialized_words_d, initialized_words_q;
103 1/1 always_comb begin initialized_words_d = initialized_words_q;
Tests: T1 T2 T3
104 // By default, we just loop through the data and wmask.
105 1/1 spi_wdata = spi_wdata_i;
Tests: T1 T2 T3
106 1/1 spi_wmask = spi_wmask_i;
Tests: T1 T2 T3
107 // If the word has not been initialized yet we modify the data and wmask to initialize all bits.
108 1/1 if (spi2sys_wr_req && !initialized_words_q[Spi2SysAw'(spi2sys_wr_addr)]) begin
Tests: T1 T2 T3
109 // Mask data at this point already and set all masked bits to 0.
110 1/1 spi_wdata = spi_wdata_i & spi_wmask_i;
Tests: T5 T20 T29
111 1/1 spi_wmask = {SramDw{1'b1}};
Tests: T5 T20 T29
112 // Mark this word as initialized
113 1/1 initialized_words_d[Spi2SysAw'(spi2sys_wr_addr)] = 1'b1;
Tests: T5 T20 T29
114 end
MISSING_ELSE
115 end
116
117 always_ff @(posedge clk_spi_i or negedge rst_spi_ni) begin : p_spi_regs
118 1/1 if (!rst_spi_ni) begin
Tests: T1 T2 T3
119 1/1 initialized_words_q <= '0;
Tests: T1 T2 T3
120 end else begin
121 1/1 initialized_words_q <= initialized_words_d;
Tests: T3 T5 T6
122 end
123 end
124
125 if (SramType == SramType2p) begin : gen_ram2p
126 prim_ram_2p_async_adv #(
127 .Depth (SramDepth),
128 .Width (SramDw), // 32 x 512 --> 2kB
129 .DataBitsPerMask (8),
130
131 .EnableECC (0),
132 .EnableParity (1),
133 .EnableInputPipeline (0),
134 .EnableOutputPipeline(0)
135 ) u_memory_2p (
136 .clk_a_i (clk_sys_i),
137 .rst_a_ni (rst_sys_ni),
138
139 .clk_b_i (clk_spi_i),
140 .rst_b_ni (rst_spi_ni),
141
142 .a_req_i (sys_req_i),
143 .a_write_i (sys_write_i),
144 .a_addr_i (sys_addr_i),
145 .a_wdata_i (sys_wdata_i),
146 .a_wmask_i (sys_wmask_i),
147 .a_rvalid_o (sys_rvalid_o),
148 .a_rdata_o (sys_rdata_o),
149 .a_rerror_o (sys_rerror_o),
150
151 .b_req_i (spi_req_i),
152 .b_write_i (spi_write_i),
153 .b_addr_i (spi_addr_i),
154 // Use modified wdata and wmask
155 .b_wdata_i (spi_wdata),
156 .b_wmask_i (spi_wmask),
157 .b_rvalid_o (spi_rvalid_o),
158 .b_rdata_o (spi_rdata_o),
159 .b_rerror_o (spi_rerror_o),
160
161 .cfg_i
162 );
163
164 logic sys2spi_unused;
165 1/1 assign sys2spi_unused = ^{
Tests: T1 T2 T3
166 sys2spi_wr_req,
167 sys2spi_wr_addr,
168 sys2spi_rd_req,
169 sys2spi_rd_addr
170 };
171
172 logic spi2sys_unused;
173 1/1 assign spi2sys_unused = ^{
Tests: T1 T2 T3
Cond Coverage for Module :
spid_dpram
| Total | Covered | Percent |
Conditions | 16 | 12 | 75.00 |
Logical | 16 | 12 | 75.00 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 64
EXPRESSION ((sys_addr_i < Sys2SpiEnd) & sys_req_i & sys_write_i)
------------1------------ ----2---- -----3-----
-1- | -2- | -3- | Status | Tests |
0 | 1 | 1 | Not Covered | |
1 | 0 | 1 | Not Covered | |
1 | 1 | 0 | Not Covered | |
1 | 1 | 1 | Covered | T4,T5,T6 |
LINE 70
EXPRESSION (spi_req_i & ((!spi_write_i)))
----1---- --------2-------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T20,T29 |
1 | 1 | Covered | T5,T12,T14 |
LINE 83
EXPRESSION (spi_req_i & spi_write_i)
----1---- -----2-----
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Covered | T5,T12,T14 |
1 | 1 | Covered | T5,T20,T29 |
LINE 91
EXPRESSION (sys_req_i & ((!sys_write_i)))
----1---- --------2-------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T4,T5,T6 |
1 | 1 | Covered | T4,T5,T25 |
LINE 108
EXPRESSION (spi2sys_wr_req && ((!initialized_words_q[7'(spi2sys_wr_addr)])))
-------1------ ----------------------2----------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T20,T29 |
1 | 1 | Covered | T5,T20,T29 |
Branch Coverage for Module :
spid_dpram
| Line No. | Total | Covered | Percent |
Branches |
|
4 |
4 |
100.00 |
IF |
108 |
2 |
2 |
100.00 |
IF |
118 |
2 |
2 |
100.00 |
108 if (spi2sys_wr_req && !initialized_words_q[Spi2SysAw'(spi2sys_wr_addr)]) begin
-1-
109 // Mask data at this point already and set all masked bits to 0.
110 spi_wdata = spi_wdata_i & spi_wmask_i;
==>
111 spi_wmask = {SramDw{1'b1}};
112 // Mark this word as initialized
113 initialized_words_d[Spi2SysAw'(spi2sys_wr_addr)] = 1'b1;
114 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T5,T20,T29 |
0 |
Covered |
T1,T2,T3 |
118 if (!rst_spi_ni) begin
-1-
119 initialized_words_q <= '0;
==>
120 end else begin
121 initialized_words_q <= initialized_words_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T3,T5,T6 |
Line Coverage for Instance : tb.dut.u_spid_dpram
| Line No. | Total | Covered | Percent |
TOTAL | | 20 | 20 | 100.00 |
CONT_ASSIGN | 64 | 1 | 1 | 100.00 |
CONT_ASSIGN | 65 | 1 | 1 | 100.00 |
CONT_ASSIGN | 70 | 1 | 1 | 100.00 |
CONT_ASSIGN | 71 | 1 | 1 | 100.00 |
CONT_ASSIGN | 83 | 1 | 1 | 100.00 |
CONT_ASSIGN | 84 | 1 | 1 | 100.00 |
CONT_ASSIGN | 91 | 1 | 1 | 100.00 |
CONT_ASSIGN | 92 | 1 | 1 | 100.00 |
ALWAYS | 103 | 7 | 7 | 100.00 |
ALWAYS | 118 | 3 | 3 | 100.00 |
CONT_ASSIGN | 165 | 1 | 1 | 100.00 |
CONT_ASSIGN | 173 | 1 | 1 | 100.00 |
63 sram_addr_t sys2spi_wr_addr;
64 1/1 assign sys2spi_wr_req = (sys_addr_i < Sys2SpiEnd) & sys_req_i & sys_write_i;
Tests: T1 T2 T3
65 1/1 assign sys2spi_wr_addr = sys_addr_i - Sys2SpiOffset;
Tests: T1 T2 T3
66
67 // SPI reads from only the Sys2Spi memory.
68 logic sys2spi_rd_req;
69 sram_addr_t sys2spi_rd_addr;
70 1/1 assign sys2spi_rd_req = spi_req_i & !spi_write_i;
Tests: T1 T2 T3
71 1/1 assign sys2spi_rd_addr = spi_addr_i - Sys2SpiOffset;
Tests: T1 T2 T3
72
73 // SPI Wr, SYS Rd is for payload upload
74 localparam sram_addr_t Spi2SysOffset = SramIngressIdx;
75 localparam int unsigned Spi2SysMinDepth = SramPayloadDepth + SramCmdFifoDepth
76 + SramAddrFifoDepth + SramTpmWrFifoDepth;
77 localparam int unsigned Spi2SysAw = $clog2(Spi2SysMinDepth);
78 localparam int unsigned Spi2SysDepth = 1 << Spi2SysAw;
79
80 // SPI writes to only the Spi2Sys memory.
81 logic spi2sys_wr_req;
82 sram_addr_t spi2sys_wr_addr;
83 1/1 assign spi2sys_wr_req = spi_req_i & spi_write_i;
Tests: T1 T2 T3
84 1/1 assign spi2sys_wr_addr = spi_addr_i - Spi2SysOffset;
Tests: T1 T2 T3
85
86 // SYS reads only read from the Spi2Sys memory.
87 // Allow all reads to complete, so the bus always gets a response, even if
88 // software chooses to read from write-only addresses.
89 logic spi2sys_rd_req;
90 sram_addr_t spi2sys_rd_addr;
91 1/1 assign spi2sys_rd_req = sys_req_i & !sys_write_i;
Tests: T1 T2 T3
92 1/1 assign spi2sys_rd_addr = sys_addr_i - Spi2SysOffset;
Tests: T1 T2 T3
93
94 // The SPI -> core buffer for the payload uses parity and SW has no way of initializing it since
95 // the write port is in the SPI domain. Since the SPI side writes the payload byte by byte,
96 // we need to guard against partially initialized 32bit words, because these could cause TL-UL
97 // bus errors upon readout. Unfortunately, an initialization circuit that initializes the entire
98 // SRAM on the SPI clock domain is infeasible since that clock is only intermittently available.
99 // Hence, we keep track of uninitialized words using a valid bit array, and upon the first write
100 // to a word, uninitialized bytes are set to zero if the write operation is a sub-word write op.
101 logic [SramDw-1:0] spi_wdata, spi_wmask;
102 logic [Spi2SysDepth-1:0] initialized_words_d, initialized_words_q;
103 1/1 always_comb begin initialized_words_d = initialized_words_q;
Tests: T1 T2 T3
104 // By default, we just loop through the data and wmask.
105 1/1 spi_wdata = spi_wdata_i;
Tests: T1 T2 T3
106 1/1 spi_wmask = spi_wmask_i;
Tests: T1 T2 T3
107 // If the word has not been initialized yet we modify the data and wmask to initialize all bits.
108 1/1 if (spi2sys_wr_req && !initialized_words_q[Spi2SysAw'(spi2sys_wr_addr)]) begin
Tests: T1 T2 T3
109 // Mask data at this point already and set all masked bits to 0.
110 1/1 spi_wdata = spi_wdata_i & spi_wmask_i;
Tests: T5 T20 T29
111 1/1 spi_wmask = {SramDw{1'b1}};
Tests: T5 T20 T29
112 // Mark this word as initialized
113 1/1 initialized_words_d[Spi2SysAw'(spi2sys_wr_addr)] = 1'b1;
Tests: T5 T20 T29
114 end
MISSING_ELSE
115 end
116
117 always_ff @(posedge clk_spi_i or negedge rst_spi_ni) begin : p_spi_regs
118 1/1 if (!rst_spi_ni) begin
Tests: T1 T2 T3
119 1/1 initialized_words_q <= '0;
Tests: T1 T2 T3
120 end else begin
121 1/1 initialized_words_q <= initialized_words_d;
Tests: T3 T5 T6
122 end
123 end
124
125 if (SramType == SramType2p) begin : gen_ram2p
126 prim_ram_2p_async_adv #(
127 .Depth (SramDepth),
128 .Width (SramDw), // 32 x 512 --> 2kB
129 .DataBitsPerMask (8),
130
131 .EnableECC (0),
132 .EnableParity (1),
133 .EnableInputPipeline (0),
134 .EnableOutputPipeline(0)
135 ) u_memory_2p (
136 .clk_a_i (clk_sys_i),
137 .rst_a_ni (rst_sys_ni),
138
139 .clk_b_i (clk_spi_i),
140 .rst_b_ni (rst_spi_ni),
141
142 .a_req_i (sys_req_i),
143 .a_write_i (sys_write_i),
144 .a_addr_i (sys_addr_i),
145 .a_wdata_i (sys_wdata_i),
146 .a_wmask_i (sys_wmask_i),
147 .a_rvalid_o (sys_rvalid_o),
148 .a_rdata_o (sys_rdata_o),
149 .a_rerror_o (sys_rerror_o),
150
151 .b_req_i (spi_req_i),
152 .b_write_i (spi_write_i),
153 .b_addr_i (spi_addr_i),
154 // Use modified wdata and wmask
155 .b_wdata_i (spi_wdata),
156 .b_wmask_i (spi_wmask),
157 .b_rvalid_o (spi_rvalid_o),
158 .b_rdata_o (spi_rdata_o),
159 .b_rerror_o (spi_rerror_o),
160
161 .cfg_i
162 );
163
164 logic sys2spi_unused;
165 1/1 assign sys2spi_unused = ^{
Tests: T1 T2 T3
166 sys2spi_wr_req,
167 sys2spi_wr_addr,
168 sys2spi_rd_req,
169 sys2spi_rd_addr
170 };
171
172 logic spi2sys_unused;
173 1/1 assign spi2sys_unused = ^{
Tests: T1 T2 T3
Cond Coverage for Instance : tb.dut.u_spid_dpram
| Total | Covered | Percent |
Conditions | 12 | 12 | 100.00 |
Logical | 12 | 12 | 100.00 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 64
EXPRESSION ((sys_addr_i < Sys2SpiEnd) & sys_req_i & sys_write_i)
------------1------------ ----2---- -----3-----
-1- | -2- | -3- | Status | Tests | Exclude Annotation |
0 | 1 | 1 | Excluded | |
VC_COV_UNR |
1 | 0 | 1 | Excluded | |
VC_COV_UNR |
1 | 1 | 0 | Excluded | |
VC_COV_UNR |
1 | 1 | 1 | Covered | T4,T5,T6 |
LINE 70
EXPRESSION (spi_req_i & ((!spi_write_i)))
----1---- --------2-------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T20,T29 |
1 | 1 | Covered | T5,T12,T14 |
LINE 83
EXPRESSION (spi_req_i & spi_write_i)
----1---- -----2-----
-1- | -2- | Status | Tests | Exclude Annotation |
0 | 1 | Excluded | |
VC_COV_UNR |
1 | 0 | Covered | T5,T12,T14 |
1 | 1 | Covered | T5,T20,T29 |
LINE 91
EXPRESSION (sys_req_i & ((!sys_write_i)))
----1---- --------2-------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T4,T5,T6 |
1 | 1 | Covered | T4,T5,T25 |
LINE 108
EXPRESSION (spi2sys_wr_req && ((!initialized_words_q[7'(spi2sys_wr_addr)])))
-------1------ ----------------------2----------------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T20,T29 |
1 | 1 | Covered | T5,T20,T29 |
Branch Coverage for Instance : tb.dut.u_spid_dpram
| Line No. | Total | Covered | Percent |
Branches |
|
4 |
4 |
100.00 |
IF |
108 |
2 |
2 |
100.00 |
IF |
118 |
2 |
2 |
100.00 |
108 if (spi2sys_wr_req && !initialized_words_q[Spi2SysAw'(spi2sys_wr_addr)]) begin
-1-
109 // Mask data at this point already and set all masked bits to 0.
110 spi_wdata = spi_wdata_i & spi_wmask_i;
==>
111 spi_wmask = {SramDw{1'b1}};
112 // Mark this word as initialized
113 initialized_words_d[Spi2SysAw'(spi2sys_wr_addr)] = 1'b1;
114 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T5,T20,T29 |
0 |
Covered |
T1,T2,T3 |
118 if (!rst_spi_ni) begin
-1-
119 initialized_words_q <= '0;
==>
120 end else begin
121 initialized_words_q <= initialized_words_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T3,T5,T6 |