Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ MAKEFILE_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

RUN_TAG = $(shell ls librelane/runs/ | tail -n 1)
TOP = chip_top
FINAL_DIR ?= $(if $(wildcard $(MAKEFILE_DIR)/final/pnl/$(TOP).pnl.v),$(MAKEFILE_DIR)/final,$(MAKEFILE_DIR)/librelane/runs/$(RUN_TAG)/final)

PDK_ROOT ?= $(MAKEFILE_DIR)/gf180mcu
PDK ?= gf180mcuD
PDK_TAG ?= 1.8.0
VENV_DIR ?= $(MAKEFILE_DIR)/.venv
VENV_PYTHON := $(VENV_DIR)/bin/python
COCOTB_PYENV_PYTHON := $(HOME)/.pyenv/versions/cocotb-env/bin/python
ifeq ($(wildcard $(VENV_PYTHON)),$(VENV_PYTHON))
PYTHON ?= $(VENV_PYTHON)
else
ifeq ($(wildcard $(COCOTB_PYENV_PYTHON)),$(COCOTB_PYENV_PYTHON))
PYTHON ?= $(COCOTB_PYENV_PYTHON)
else
PYTHON ?= python3
endif
endif

AVAILABLE_SLOTS = 1x1 0p5x1 1x0p5 0p5x0p5
DEFAULT_SLOT = 1x1
Expand Down Expand Up @@ -119,9 +125,21 @@ build-riscv-toolchain: ## Build bare-metal RISC-V GCC from third_party/riscv-gnu
.PHONY: build-riscv-toolchain

sim-gl: ## Run gate-level simulation with cocotb (after copy-final)
cd cocotb; GL=1 PDK_ROOT=${PDK_ROOT} PDK=${PDK} SLOT=${SLOT} python3 chip_top_tb.py
cd cocotb; GL=1 FINAL_DIR=$(FINAL_DIR) PDK_ROOT=${PDK_ROOT} PDK=${PDK} SLOT=${SLOT} $(PYTHON) chip_top_tb.py
.PHONY: sim-gl

sim-gl-debug-modes: ## Run gate-level chip_top debug-mode pad smoke test
cd cocotb; PYTHONPATH=$(MAKEFILE_DIR)/cocotb/sim/tb GL=1 FINAL_DIR=$(FINAL_DIR) PDK_ROOT=${PDK_ROOT} PDK=${PDK} SLOT=${SLOT} COCOTB_TEST_MODULE=test_chip_core_debug_modes COCOTB_TEST_FILTER=test_chip_top_debug_modes_force_inputs_reach_debug_bus $(PYTHON) chip_top_tb.py
.PHONY: sim-gl-debug-modes

sim-gl-sensor-bridge: ## Run full gate-level sensor-model pad bridge feature test
cd cocotb; PYTHONPATH=$(MAKEFILE_DIR)/cocotb/sim/tb GL=1 CHIP_TOPLEVEL=sim_chip_top_gl_sensor_bridge_env FINAL_DIR=$(FINAL_DIR) PDK_ROOT=${PDK_ROOT} PDK=${PDK} SLOT=${SLOT} COCOTB_TEST_MODULE=test_chip_top_gl_sensor_bridge COCOTB_TEST_FILTER=test_chip_top_gl_sensor_bridge_debug_features_match_python_reference $(PYTHON) chip_top_tb.py
.PHONY: sim-gl-sensor-bridge

sim-gl-sensor-bridge-smoke: ## Run gate-level sensor bridge connectivity smoke test
cd cocotb; PYTHONPATH=$(MAKEFILE_DIR)/cocotb/sim/tb GL=1 CHIP_TOPLEVEL=sim_chip_top_gl_sensor_bridge_env FINAL_DIR=$(FINAL_DIR) PDK_ROOT=${PDK_ROOT} PDK=${PDK} SLOT=${SLOT} COCOTB_TEST_MODULE=test_chip_top_gl_sensor_bridge COCOTB_TEST_FILTER=test_chip_top_gl_sensor_bridge_reaches_models $(PYTHON) chip_top_tb.py
.PHONY: sim-gl-sensor-bridge-smoke

sim-view: ## View simulation waveforms in GTKWave
gtkwave cocotb/sim_build/chip_top.fst
.PHONY: sim-view
Expand Down
5 changes: 5 additions & 0 deletions cocotb/chip_top_tb.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ async def test_chip_top_feature_inject(dut):

def chip_top_runner():
proj_path = Path(__file__).resolve().parent
final_path = Path(final_dir).expanduser() if final_dir else proj_path / "../final"
gl_netlist = final_path / "pnl" / f"{netlist_toplevel}.pnl.v"

sources = []
# Compile with SIM define so the sim bus and sensor models are active.
Expand All @@ -307,6 +309,8 @@ def chip_top_runner():
sources.append(Path(pdk_root) / pdk / "libs.ref" / scl / "verilog" / "primitives.v")
sources.append(proj_path / f"../final/pnl/{hdl_toplevel}.pnl.v")
defines = {"FUNCTIONAL": True, "USE_POWER_PINS": True}
if hdl_toplevel == "sim_chip_top_gl_sensor_bridge_env":
defines["SENSOR_SIM_PAD_BRIDGE"] = True
else:
src_dir = proj_path / "../src"
pad_level = hdl_toplevel in {"chip_top", "chip_top_sim_wrap"}
Expand Down Expand Up @@ -366,6 +370,7 @@ def chip_top_runner():
runner.test(
hdl_toplevel=hdl_toplevel,
test_module=test_module,
test_filter=test_filter,
plusargs=plusargs,
waves=True,
)
Expand Down
34 changes: 19 additions & 15 deletions cocotb/sensors/i2c_slave_adpd144ri.sv
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ module i2c_slave_adpd144ri #(
RSP_WRITE = 3'd4
} rsp_state_t;

rsp_state_t rsp_state;
reg [1:0] byte_cnt;
reg [7:0] bytes_left;
rsp_state_t rsp_state;
reg [1:0] byte_cnt;
reg [7:0] bytes_left;
reg sim_req_q;
wire sim_req_rise = sim_req && !sim_req_q;

initial begin
if (!$value$plusargs("DATA_DIR=%s", data_dir))
Expand Down Expand Up @@ -94,20 +96,22 @@ module i2c_slave_adpd144ri #(
sim_rdata <= 8'h00;
sim_rvalid <= 1'b0;
sim_rlast <= 1'b0;
sim_err <= 1'b0;
rsp_state <= RSP_IDLE;
byte_cnt <= 2'd0;
bytes_left <= 8'd0;
end else begin
sim_ack <= 1'b0;
sim_rvalid <= 1'b0;
sim_rlast <= 1'b0;
sim_err <= 1'b0;
rsp_state <= RSP_IDLE;
byte_cnt <= 2'd0;
bytes_left <= 8'd0;
sim_req_q <= 1'b0;
end else begin
sim_req_q <= sim_req;
sim_ack <= 1'b0;
sim_rvalid <= 1'b0;
sim_rlast <= 1'b0;
sim_err <= 1'b0;

case (rsp_state)
RSP_IDLE: begin
if (sim_req && (sim_addr == I2C_ADDR)) begin
sim_ack <= 1'b1;
case (rsp_state)
RSP_IDLE: begin
if (sim_req_rise && (sim_addr == I2C_ADDR)) begin
sim_ack <= 1'b1;
byte_cnt <= 2'd0;
if (sim_write) begin
rsp_state <= RSP_WRITE;
Expand Down
30 changes: 17 additions & 13 deletions cocotb/sensors/i2c_slave_lis2dw12.sv
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ module i2c_slave_lis2dw12 #(
RSP_DATA = 2'd2
} rsp_state_t;

rsp_state_t rsp_state;
reg [2:0] byte_cnt;
rsp_state_t rsp_state;
reg [2:0] byte_cnt;
reg sim_req_q;
wire sim_req_rise = sim_req && !sim_req_q;

initial begin
if (!$value$plusargs("DATA_DIR=%s", data_dir))
Expand Down Expand Up @@ -84,19 +86,21 @@ module i2c_slave_lis2dw12 #(
sim_rdata <= 8'h00;
sim_rvalid <= 1'b0;
sim_rlast <= 1'b0;
sim_err <= 1'b0;
rsp_state <= RSP_IDLE;
byte_cnt <= '0;
end else begin
sim_ack <= 1'b0;
sim_rvalid <= 1'b0;
sim_rlast <= 1'b0;
sim_err <= 1'b0;
rsp_state <= RSP_IDLE;
byte_cnt <= '0;
sim_req_q <= 1'b0;
end else begin
sim_req_q <= sim_req;
sim_ack <= 1'b0;
sim_rvalid <= 1'b0;
sim_rlast <= 1'b0;
sim_err <= 1'b0;

case (rsp_state)
RSP_IDLE: begin
if (sim_req && (sim_addr == I2C_ADDR)) begin
sim_ack <= 1'b1;
case (rsp_state)
RSP_IDLE: begin
if (sim_req_rise && (sim_addr == I2C_ADDR)) begin
sim_ack <= 1'b1;
if (sim_reg == REG_STATUS) begin
rsp_state <= RSP_STATUS;
end else if (sim_reg == REG_DATA) begin
Expand Down
165 changes: 165 additions & 0 deletions cocotb/sim/tb/sim_chip_top_gl_sensor_bridge_env.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
`timescale 1ns/1ps

module sim_chip_top_gl_sensor_bridge_env;
localparam [6:0] ACC_ADDR = 7'h19;
localparam [6:0] PPG_ADDR = 7'h64;

logic clk_drv = 1'b0;
logic rst_n_drv = 1'b0;
logic [11:0] input_drv = 12'h000;
wire clk_PAD;
wire rst_n_PAD;
wire [11:0] input_PAD;
logic [39:0] bidir_drv = 40'h0;
logic [39:0] bidir_oe = 40'h0;
wire [39:0] bidir_PAD;
wire [39:0] bidir_sample;
wire [1:0] analog_PAD;

wire VDD = 1'b1;
wire VSS = 1'b0;

wire sensor_bridge_en = input_drv[11];

wire sim_req = bidir_PAD[8];
wire sim_write = bidir_PAD[9];
wire [6:0] sim_addr = bidir_PAD[16:10];
wire [7:0] sim_reg = bidir_PAD[24:17];
wire [7:0] sim_len = bidir_PAD[32:25];
wire [7:0] sim_wdata = bidir_PAD[7:0];
wire sensor_req = sensor_bridge_en ? sim_req : 1'b0;
wire sensor_write = sensor_bridge_en ? sim_write : 1'b0;
wire [6:0] sensor_addr = sensor_bridge_en ? sim_addr : 7'h00;
wire [7:0] sensor_reg = sensor_bridge_en ? sim_reg : 8'h00;
wire [7:0] sensor_len = sensor_bridge_en ? sim_len : 8'h00;
wire [7:0] sensor_wdata = sensor_bridge_en ? sim_wdata : 8'h00;

wire accel_sim_ack;
wire [7:0] accel_sim_rdata;
wire accel_sim_rvalid;
wire accel_sim_rlast;
wire accel_sim_err;

wire ppg_sim_ack;
wire [7:0] ppg_sim_rdata;
wire ppg_sim_rvalid;
wire ppg_sim_rlast;
wire ppg_sim_err;

wire sensor_sim_ack = (sensor_addr == ACC_ADDR) ? accel_sim_ack :
(sensor_addr == PPG_ADDR) ? ppg_sim_ack : 1'b0;
wire [7:0] sensor_sim_rdata = (sensor_addr == ACC_ADDR) ? accel_sim_rdata :
(sensor_addr == PPG_ADDR) ? ppg_sim_rdata : 8'h00;
wire sensor_sim_rvalid = (sensor_addr == ACC_ADDR) ? accel_sim_rvalid :
(sensor_addr == PPG_ADDR) ? ppg_sim_rvalid : 1'b0;
wire sensor_sim_rlast = (sensor_addr == ACC_ADDR) ? accel_sim_rlast :
(sensor_addr == PPG_ADDR) ? ppg_sim_rlast : 1'b0;
wire sensor_sim_err = (sensor_addr == ACC_ADDR) ? accel_sim_err :
(sensor_addr == PPG_ADDR) ? ppg_sim_err : 1'b1;

logic sensor_sim_ack_pad_q;
logic sensor_sim_rvalid_pad_q;
logic [7:0] sensor_sim_rdata_pad_q;
logic sensor_sim_rlast_pad_q;
logic sensor_sim_err_pad_q;

// Sensor models update on the rising edge, like the GL netlist. Retiming the
// pad response on the falling edge makes the external pads stable before the
// chip samples them on the next rising edge.
always_ff @(negedge clk_PAD or negedge rst_n_PAD) begin
if (!rst_n_PAD) begin
sensor_sim_ack_pad_q <= 1'b0;
sensor_sim_rvalid_pad_q <= 1'b0;
sensor_sim_rdata_pad_q <= 8'h00;
sensor_sim_rlast_pad_q <= 1'b0;
sensor_sim_err_pad_q <= 1'b0;
end else if (!sensor_bridge_en) begin
sensor_sim_ack_pad_q <= 1'b0;
sensor_sim_rvalid_pad_q <= 1'b0;
sensor_sim_rdata_pad_q <= 8'h00;
sensor_sim_rlast_pad_q <= 1'b0;
sensor_sim_err_pad_q <= 1'b0;
end else begin
sensor_sim_ack_pad_q <= sensor_sim_ack;
sensor_sim_rvalid_pad_q <= sensor_sim_rvalid;
sensor_sim_rdata_pad_q <= sensor_sim_rdata;
sensor_sim_rlast_pad_q <= sensor_sim_rlast;
sensor_sim_err_pad_q <= sensor_sim_err;
end
end

assign bidir_sample = bidir_PAD;
assign clk_PAD = clk_drv;
assign rst_n_PAD = rst_n_drv;
assign input_PAD = input_drv;

genvar i;
generate
for (i = 0; i < 40; i = i + 1) begin : tb_bidir_drive
if (i < 8) begin : sensor_data_drive
assign bidir_PAD[i] = sensor_bridge_en ? (sensor_sim_rvalid_pad_q ? sensor_sim_rdata_pad_q[i] : 1'bz) :
(bidir_oe[i] ? bidir_drv[i] : 1'bz);
end else if (i == 33) begin : sensor_ack_drive
assign bidir_PAD[i] = sensor_bridge_en ? sensor_sim_ack_pad_q :
(bidir_oe[i] ? bidir_drv[i] : 1'bz);
end else if (i == 34) begin : sensor_rvalid_drive
assign bidir_PAD[i] = sensor_bridge_en ? sensor_sim_rvalid_pad_q :
(bidir_oe[i] ? bidir_drv[i] : 1'bz);
end else if (i == 35) begin : sensor_rlast_drive
assign bidir_PAD[i] = sensor_bridge_en ? sensor_sim_rlast_pad_q :
(bidir_oe[i] ? bidir_drv[i] : 1'bz);
end else if (i == 36) begin : sensor_err_drive
assign bidir_PAD[i] = sensor_bridge_en ? sensor_sim_err_pad_q :
(bidir_oe[i] ? bidir_drv[i] : 1'bz);
end else begin : external_drive
assign bidir_PAD[i] = bidir_oe[i] ? bidir_drv[i] : 1'bz;
end
end
endgenerate

pullup host_sda_pullup (bidir_PAD[6]);

i2c_slave_lis2dw12 #(
.I2C_ADDR(ACC_ADDR)
) u_accel_slave (
.clk(clk_PAD),
.resetn(rst_n_PAD),
.sim_req(sensor_req),
.sim_addr(sensor_addr),
.sim_reg(sensor_reg),
.sim_len(sensor_len),
.sim_ack(accel_sim_ack),
.sim_rdata(accel_sim_rdata),
.sim_rvalid(accel_sim_rvalid),
.sim_rlast(accel_sim_rlast),
.sim_err(accel_sim_err)
);

i2c_slave_adpd144ri #(
.I2C_ADDR(PPG_ADDR)
) u_ppg_slave (
.clk(clk_PAD),
.resetn(rst_n_PAD),
.sim_req(sensor_req),
.sim_addr(sensor_addr),
.sim_reg(sensor_reg),
.sim_len(sensor_len),
.sim_write(sensor_write),
.sim_wdata(sensor_wdata),
.sim_ack(ppg_sim_ack),
.sim_rdata(ppg_sim_rdata),
.sim_rvalid(ppg_sim_rvalid),
.sim_rlast(ppg_sim_rlast),
.sim_err(ppg_sim_err)
);

chip_top u_chip (
.VDD(VDD),
.VSS(VSS),
.clk_PAD(clk_PAD),
.rst_n_PAD(rst_n_PAD),
.input_PAD(input_PAD),
.bidir_PAD(bidir_PAD),
.analog_PAD(analog_PAD)
);
endmodule
Loading
Loading