---
# System prepended metadata

title: Week 4- Questions

---

## Week-4 Questions

### Topic 1 : RTL-synthesis consistency
#### Question : Evaluate the blocking and non-blocking assignment
![image](https://hackmd.io/_uploads/rJPo9423Je.png) 
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?
![image](https://hackmd.io/_uploads/BJrzzI32kl.png)
* 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 ?
![image](https://hackmd.io/_uploads/S1qUzPnhJx.png)
* 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
![image](https://hackmd.io/_uploads/Bk_7EPh31g.png)

Refer to Lab3 fir:
1. Draw Waveform of tvalid, tready, tdata, muxsel, ffen, addr, rdata, tdata
![image](https://hackmd.io/_uploads/ByueODh3ye.png)
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
![DE9CECA4-0316-4019-B710-9C047BD3A0BC (1)](https://hackmd.io/_uploads/SkWEOwnhke.jpg)
---
### Topic 3 : FSM
#### Question : Refer to the timing waveform, is it a Moore or Mealy Machine?
![image](https://hackmd.io/_uploads/HJDuKwn2ke.png)
* 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?

![image](https://hackmd.io/_uploads/H19bY4hhyg.png)

* 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 
![image](https://hackmd.io/_uploads/SJgkkunh1g.png)
|     Reset Type     | Verilog | Waveform | Schematic |
|:------------------:|:-------:|:--------:|:---------:|
| Synchronous Reset  |    A    |    B     |     B     |
| Asynchronous Reset |    B    |    A     |     A     |

