## 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 |