## Week-4 Questions
### Topic 1 : RTL-synthesis consistency
#### Question : Evaluate the blocking and non-blocking assignment

1. Are the following two Verilog codes produce the same circuit?
Yes, they produce the same circuit (**same synthesis results**)
2. When b = 1, c = 0, and a changes form 0 to 1, what is the final value of x and y for circuit A and B ?
(1) Non-blocking
```verilog=
always @(a or b or c) begin
x <= a & b;
y <= x | c;
end
```
When a = 0, b = 1, c = 0:
```
x <= 0 & 1 = 0 // x is updated later
y <= x | 0 = x // the old value of x is used for computing y
```
When a = 1, b = 1, c = 0:
```
x <= 1 & 1 = 1
y <= 0 | 0 = 0
```
(2) Blocking
```verilog=
always @(a or b or c) begin
x = a & b;
y = x | c;
end
```
When a = 0, b = 1, c = 0:
```
x = 0 & 1 = 0 // execute first
y = 0 | 0 = 0 // execute in order, so execute next
```
When a = 1, b = 1, c = 0:
```
x = 1 & 1 = 1
y = 1 | 0 = 1
```
| Circuit | Final `x` | Final `y` |
| -------------------- |:---------:|:---------:|
| **A (Non-Blocking)** | 1 | 0 |
| **B (Blocking)** | 1 | 1 |
**Combinational logic is suggested to use blocking logic.**
---
#### Question : What is the logic/gate generated from the code4a, and code4b?

* code4a : Without full case, incomplete case
```Verilog
// More gates, extra AND logic
y[0] = en & a[0] & a[1]
y[1] = en & (a[0])' & a[1]
y[2] = en & a[0] & (a[1])'
y[3] = en & (a[0])' & (a[1])'
```
* code4b : With full case, `en = 0` becomes don't care
```Verilog
// Fewer gates, optimized logic
y[0] = a[0] & a[1]
y[1] = (a[0])' & a[1]
y[2] = a[0] & (a[1])'
y[3] = (a[0])' & (a[1])'
```
---
#### Question : What is logic/gate generated from code5a, and code5b ?

* code5a : Without synopsys parallel case
```verilog
// extra inverter and timing path
z = a & b
y = z' & c & d
```
* code5b : With synopsys parallel case
```verilog
// optimized gate and timing
z = a & b
y = c & d
```
---
### Topic 2 : Construct design
(TBD)
#### Question :
Design an axi-stream interface with SRAM (1T read latency)To achieve 1-1-1 back-to-back data transfer

Refer to Lab3 fir:
1. Draw Waveform of tvalid, tready, tdata, muxsel, ffen, addr, rdata, tdata

2. Write the Verilog code
```verilog=
// 1. data ram signal
// initialize address
always@(posedge axis_clk or negedge axis_rst_n) begin
if(!axis_rst_n) begin
addr_cnt <= 0;
end else if(state == DONE)begin
addr_cnt <= 0;
end else begin
addr_cnt <= (addr_cnt == 31) ? addr_cnt : addr_cnt + 1;
end
end
// bram for data ram signal
always@* begin
data_EN = 1'b1;
if(state == CALC) begin
data_WE = (ss_tvalid && ss_tready) ? 4'b1111 : 4'b0000;
data_Di = (ss_tvalid && ss_tready) ? ss_tdata_latch : 32'h00;
data_A = (ss_tvalid && ss_tready) ? 4 * x_w_cnt : 4 * x_r_cnt;
end else if(state == IDLE || state == DONE) begin
data_WE = 4'b1111;
data_Di = 32'h00;
data_A = 4 * addr_cnt;
end else begin
data_WE = 4'b0000;
data_Di = 32'h00;
data_A = 0;
end
end
// 2. address generator for core engine operation
// address generator for newly stored data (up Counter)
assign x_w_cnt_tmp = (ss_tready && ss_tvalid) ?
((x_w_cnt == tap_num - 1) ? 0 : (x_w_cnt + 1)) :
x_w_cnt;
// address generator for reading out data (down Counter)
always @* begin
if(ss_tready && ss_tvalid) begin
x_r_cnt_tmp = x_w_cnt_tmp;
end else if (data_state == DT_PROC) begin
if(x_r_cnt == 0) begin
x_r_cnt_tmp = tap_num - 1;
end else begin
x_r_cnt_tmp = x_r_cnt - 1;
end
end else begin
x_r_cnt_tmp = x_w_cnt + 1;
end
end
always@ (posedge axis_clk or negedge axis_rst_n) begin
if(!axis_rst_n) begin
x_w_cnt <= tap_num - 1;
x_r_cnt <= 0;
end else if(ap_ctrl[0] == 1)begin
x_w_cnt <= 0;
x_r_cnt <= 0;
end else begin
x_w_cnt <= x_w_cnt_tmp;
x_r_cnt <= x_r_cnt_tmp;
end
end
// 3. data transfer fsm : determine when to recieve and send data
always@* begin
case(data_state)
DT_WAIT: begin
if(ss_tvalid) begin
next_data_state = DT_PROC;
next_ss_tready = 0;
next_sm_tvalid = 0;
end else begin
next_data_state = DT_WAIT;
next_ss_tready = 1;
next_sm_tvalid = 0;
end
end
DT_PROC: begin
if(tap_cnt == (4 + (tap_num - 1))) begin
next_data_state = DT_DONE;
next_ss_tready = 0;
next_sm_tvalid = 1;
end else begin
next_data_state = DT_PROC;
next_ss_tready = 0;
next_sm_tvalid = 0;
end
end
DT_DONE: begin
if(sm_tready) begin
if(y_cnt == data_length - 1) begin
next_data_state = DT_IDLE;
next_ss_tready = 0;
next_sm_tvalid = 0;
end else begin
next_data_state = DT_WAIT;
next_ss_tready = 1;
next_sm_tvalid = 0;
end
end else begin
next_data_state = DT_DONE;
next_ss_tready = 0;
next_sm_tvalid = 1;
end
end
DT_IDLE:begin
if(awaddr == 12'h00 && wdata [0] == 1'b1 && awready && wready) begin
next_data_state = DT_WAIT;
next_ss_tready = 1;
next_sm_tvalid = 0;
end else begin
next_data_state = DT_IDLE;
next_ss_tready = 0;
next_sm_tvalid = 0;
end
end
default : begin
next_data_state = DT_WAIT;
next_sm_tvalid = 0;
next_ss_tready = 0;
end
endcase
end
always@(posedge axis_clk or negedge axis_rst_n) begin
if(!axis_rst_n) begin
data_state <= DT_IDLE;
ss_tready <= 0;
ss_tdata_latch <= 0;
sm_tvalid <= 0;
sm_tdata <= 32'h00;
end else if(state == IDLE) begin
data_state <= next_data_state;
ss_tready <= next_ss_tready;
ss_tdata_latch <= 0;
sm_tvalid <= next_sm_tvalid;
sm_tdata <= 32'h00;
end else begin
data_state <= next_data_state;
ss_tready <= next_ss_tready;
ss_tdata_latch <= (ss_tvalid && ss_tready) ? ss_tdata : ss_tdata_latch;
sm_tvalid <= next_sm_tvalid;
sm_tdata <= sm_tdata_tmp;
end
end
assign sm_tdata_tmp = (tap_cnt == (4 + (tap_num - 1))) ? y : sm_tdata;
```
3. Run the simulation

---
### Topic 3 : FSM
#### Question : Refer to the timing waveform, is it a Moore or Mealy Machine?

* Mealy machine : Output depends on both the current state and the input
* Moore machine : Output depends only on the current state
It is a **Moore machine** because it only changes its output with the clock edge, which is related to the FSM states, but does not change with the input.
---
### Topic 4 : SRAM
#### Question : In ASIC flow, How to write verilog code to create SRAM?

* In ASIC flow, if synthesizing the given Verilog code using a design compiler, we will get **a bunch of registers**. This is because the code uses a **reg array**, which is typically inferred as **flip-flops (registers)** in synthesis tools rather than actual SRAM.
* Instantiate a SRAM
```verilog=
module sram (
input wire clk,
input wire we,
input wire [4:0] wa, // Write Address (assuming 32-depth)
input wire [4:0] ra, // Read Address
input wire [63:0] di, // Data Input
output wire [63:0] do // Data Output
);
sram_32x64 my_sram (
.CLK(clk),
.WE(we),
.WA(wa),
.RA(ra),
.DI(di),
.DO(do)
);
endmodule
```
---
### Topic 5 : Reset
#### Question : Select the Verilog code, Waveform, Schematic for Synchronous/Asynchronous Reset

| Reset Type | Verilog | Waveform | Schematic |
|:------------------:|:-------:|:--------:|:---------:|
| Synchronous Reset | A | B | B |
| Asynchronous Reset | B | A | A |