mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-09-15 10:31:41 -04:00
Make initial public release
This commit is contained in:
commit
715de60f4a
251 changed files with 881225 additions and 0 deletions
291
hw/application_fpga/Makefile
Normal file
291
hw/application_fpga/Makefile
Normal file
|
@ -0,0 +1,291 @@
|
|||
#=======================================================================
|
||||
#
|
||||
# Makefile
|
||||
# --------
|
||||
# Makefile for building, simulating, running all application_fpga
|
||||
# HW targets as well as its firmware.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 2022 - Tillitis AB
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
#=======================================================================
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Defines.
|
||||
#-------------------------------------------------------------------
|
||||
SHELL := /bin/bash
|
||||
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
P := $(CUR_DIR)
|
||||
|
||||
YOSYS_PATH ?=
|
||||
NEXTPNR_PATH ?=
|
||||
ICESTORM_PATH ?=
|
||||
|
||||
# Size in 32-bit words
|
||||
BRAM_FW_SIZE ?= 2048
|
||||
|
||||
PIN_FILE ?= application_fpga_mta1_usb_v1.pcf
|
||||
|
||||
SIZE ?= llvm-size-14
|
||||
OBJCOPY ?= llvm-objcopy-14
|
||||
|
||||
CC = clang-14
|
||||
|
||||
CFLAGS = -target riscv32-unknown-none-elf -march=rv32imc -mabi=ilp32 \
|
||||
-static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf \
|
||||
-fno-builtin-putchar -nostdlib -mno-relax -Wall -flto
|
||||
|
||||
AS = clang-14
|
||||
ASFLAGS = -target riscv32-unknown-none-elf -march=rv32imc -mabi=ilp32 -mno-relax
|
||||
|
||||
ICE40_SIM_CELLS = $(shell yosys-config --datdir/ice40/cells_sim.v)
|
||||
|
||||
|
||||
# FPGA source files.
|
||||
TOP_SRC = $(P)/rtl/application_fpga.v
|
||||
|
||||
VERILATOR_TOP_SRC = $(P)/tb/application_fpga_vsim.v
|
||||
|
||||
VERILOG_SRCS = \
|
||||
$(P)/rtl/reset_gen.v \
|
||||
$(P)/rtl/ram.v \
|
||||
$(P)/rtl/rom.v \
|
||||
$(P)/core/picorv32/rtl/picorv32.v \
|
||||
$(P)/core/timer/rtl/timer_core.v \
|
||||
$(P)/core/timer/rtl/timer.v \
|
||||
$(P)/core/uds/rtl/uds.v \
|
||||
$(P)/core/touch_sense/rtl/touch_sense.v \
|
||||
$(P)/core/mta1/rtl/mta1.v \
|
||||
$(P)/core/uart/rtl/uart_core.v \
|
||||
$(P)/core/uart/rtl/uart_fifo.v \
|
||||
$(P)/core/uart/rtl/uart.v \
|
||||
$(P)/core/trng/rtl/firo.v \
|
||||
$(P)/core/trng/rtl/garo.v \
|
||||
$(P)/core/trng/rtl/figaro_core.v \
|
||||
$(P)/core/trng/rtl/figaro.v
|
||||
|
||||
FIRMWARE_DEPS = \
|
||||
$(P)/fw/mta1_mkdf_mem.h \
|
||||
$(P)/fw/mta1_mkdf/types.h \
|
||||
$(P)/fw/mta1_mkdf/lib.h \
|
||||
$(P)/fw/mta1_mkdf/proto.h
|
||||
|
||||
FIRMWARE_OBJS = \
|
||||
$(P)/fw/mta1_mkdf/main.o \
|
||||
$(P)/fw/mta1_mkdf/start.o \
|
||||
$(P)/fw/mta1_mkdf/proto.o \
|
||||
$(P)/fw/mta1_mkdf/lib.o \
|
||||
$(P)/fw/mta1_mkdf/blake2s/blake2s.o
|
||||
|
||||
TESTFW_OBJS = \
|
||||
$(P)/fw/testfw/main.o \
|
||||
$(P)/fw/mta1_mkdf/start.o \
|
||||
$(P)/fw/mta1_mkdf/proto.o \
|
||||
$(P)/fw/mta1_mkdf/lib.o
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# All: Complete build of HW and FW.
|
||||
#-------------------------------------------------------------------
|
||||
all: application_fpga.bin
|
||||
.PHONY: all
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# The size_mismatch target make sure that we don't end up with an
|
||||
# incorrect BRAM_FW_SIZE
|
||||
# -------------------------------------------------------------------
|
||||
size_mismatch: firmware.elf
|
||||
@test $$($(SIZE) $< | awk 'NR==2{print $$4}') -le $$(( 32 / 8 * $(BRAM_FW_SIZE) )) || \
|
||||
(echo "The 'BRAM_FW_SIZE' variable needs to be increased" && false)
|
||||
.PHONY: size_mismatch
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Firmware generation.
|
||||
# Included in the bitstream.
|
||||
#-------------------------------------------------------------------
|
||||
LDFLAGS=-T $(P)/fw/mta1_mkdf/firmware.lds
|
||||
|
||||
$(FIRMWARE_OBJS): $(FIRMWARE_DEPS)
|
||||
$(TESTFW_OBJS): $(FIRMWARE_DEPS)
|
||||
|
||||
firmware.elf: $(FIRMWARE_OBJS) $(P)/fw/mta1_mkdf/firmware.lds
|
||||
$(CC) $(CFLAGS) $(FIRMWARE_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
testfw.elf: $(TESTFW_OBJS) $(P)/fw/mta1_mkdf/firmware.lds
|
||||
$(CC) $(CFLAGS) $(TESTFW_OBJS) $(LDFLAGS) -o $@
|
||||
|
||||
# Generate a fake BRAM file that will be filled in later after place-n-route
|
||||
bram_fw.hex:
|
||||
$(ICESTORM_PATH)icebram -v -g 32 $(BRAM_FW_SIZE) > $@
|
||||
|
||||
firmware.hex: firmware.bin size_mismatch
|
||||
python3 $(P)/tools/makehex/makehex.py $< $(BRAM_FW_SIZE) > $@
|
||||
testfw.hex: testfw.bin size_mismatch
|
||||
python3 $(P)/tools/makehex/makehex.py $< $(BRAM_FW_SIZE) > $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(SIZE) $<
|
||||
$(OBJCOPY) --input-target=elf32-littleriscv --output-target=binary $< $@
|
||||
chmod -x $@
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Source linting.
|
||||
#-------------------------------------------------------------------
|
||||
LINT=verilator
|
||||
LINT_FLAGS = +1364-2001ext+ --lint-only -Wall -Wno-fatal -Wno-DECLFILENAME \
|
||||
--timescale 1ns/1ns -DNO_ICE40_DEFAULT_ASSIGNMENTS
|
||||
|
||||
lint: $(TOP_SRC) $(VERILOG_SRCS) $(ICE40_SIM_CELLS)
|
||||
$(LINT) $(LINT_FLAGS) \
|
||||
-DBRAM_FW_SIZE=$(BRAM_FW_SIZE) \
|
||||
-DFIRMWARE_HEX=\"$(P)/firmware.hex\" \
|
||||
-DUDS_HEX=\"$(P)/data/uds.hex\" \
|
||||
-DUDI_HEX=\"$(P)/data/udi.hex\" \
|
||||
--top-module application_fpga $^
|
||||
.PHONY: lint
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Build Verilator compiled simulation for the design.
|
||||
#-------------------------------------------------------------------
|
||||
verilator: $(VERILATOR_TOP_SRC) $(VERILOG_SRCS) firmware.hex $(ICE40_SIM_CELLS) \
|
||||
$(P)/tb/application_fpga_verilator.cc
|
||||
verilator --timescale 1ns/1ns -DNO_ICE40_DEFAULT_ASSIGNMENTS \
|
||||
-Wall -Wno-COMBDLY -Wno-lint \
|
||||
-DBRAM_FW_SIZE=$(BRAM_FW_SIZE) \
|
||||
-DFIRMWARE_HEX=\"$(P)/firmware.hex\" \
|
||||
-DUDS_HEX=\"$(P)/data/uds.hex\" \
|
||||
-DUDI_HEX=\"$(P)/data/udi.hex\" \
|
||||
--cc --exe --Mdir verilated --top-module application_fpga \
|
||||
$(filter %.v, $^) $(filter %.cc, $^)
|
||||
make -C verilated -f Vapplication_fpga.mk
|
||||
.PHONY: verilator
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Main FPGA build flow.
|
||||
# Synthesis. Place & Route. Bitstream generation.
|
||||
#-------------------------------------------------------------------
|
||||
synth.json: $(TOP_SRC) $(VERILOG_SRCS) bram_fw.hex
|
||||
$(YOSYS_PATH)yosys -v3 -l synth.log -DBRAM_FW_SIZE=$(BRAM_FW_SIZE) \
|
||||
-DFIRMWARE_HEX=\"$(P)/bram_fw.hex\" \
|
||||
-DUDS_HEX=\"$(P)/data/uds.hex\" \
|
||||
-DUDI_HEX=\"$(P)/data/udi.hex\" \
|
||||
-p 'synth_ice40 -dsp -top application_fpga -json $@; write_verilog -attr2comment synth.v' \
|
||||
$(filter %.v, $^)
|
||||
|
||||
application_fpga.asc: synth.json $(P)/data/$(PIN_FILE)
|
||||
$(NEXTPNR_PATH)nextpnr-ice40 --ignore-loops --up5k --package sg48 --json $< \
|
||||
--pcf $(P)/data/$(PIN_FILE) --asc $@
|
||||
|
||||
application_fpga.bin: application_fpga.asc bram_fw.hex firmware.hex
|
||||
$(ICESTORM_PATH)icebram -v bram_fw.hex firmware.hex < $< > $<.tmp
|
||||
$(ICESTORM_PATH)icepack $<.tmp $@
|
||||
@-$(RM) $<.tmp
|
||||
|
||||
application_fpga_testfw.bin: application_fpga.asc bram_fw.hex testfw.hex
|
||||
$(ICESTORM_PATH)icebram -v bram_fw.hex testfw.hex < $< > $<.tmp
|
||||
$(ICESTORM_PATH)icepack $<.tmp $@
|
||||
@-$(RM) $<.tmp
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# post-synthesis functional simulation.
|
||||
#-------------------------------------------------------------------
|
||||
synth_tb.vvp: $(P)/tb/tb_application_fpga.v synth.json
|
||||
iverilog -o $@ -s tb_application_fpga synth.v $(P)/tb/tb_application_fpga.v \
|
||||
-DNO_ICE40_DEFAULT_ASSIGNMENTS $(ICE40_SIM_CELLS)
|
||||
chmod -x $@
|
||||
|
||||
synth_sim: synth_tb.vvp
|
||||
vvp -N $<
|
||||
.PHONY: synth_sim
|
||||
|
||||
synth_sim_vcd: synth_tb.vvp
|
||||
vvp -N $< +vcd
|
||||
.PHONY: synth_sim_vcd
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# post-place and route functional simulation.
|
||||
#-------------------------------------------------------------------
|
||||
route.v: application_fpga.asc $(P)/data/$(PIN_FILE)
|
||||
icebox_vlog -L -n application_fpga -sp $(P)/data/$(PIN_FILE) $< > $@
|
||||
|
||||
route_tb.vvp: route.v tb/tb_application_fpga.v
|
||||
iverilog -o $@ -s tb_application_fpga $^ $(ICE40_SIM_CELLS)
|
||||
chmod -x $@
|
||||
|
||||
route_sim: route_tb.vvp
|
||||
vvp -N $<
|
||||
.PHONY: route_sim
|
||||
|
||||
route_sim_vcd: route_tb.vvp
|
||||
vvp -N $< +vcd
|
||||
.PHONY: route_sim_vcd
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# FPGA device programming.
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
prog_flash: application_fpga.bin
|
||||
sudo tillitis-iceprog $<
|
||||
.PHONY: prog_flash
|
||||
|
||||
prog_flash_testfw: application_fpga_testfw.bin
|
||||
sudo tillitis-iceprog $<
|
||||
.PHONY: prog_flash_testfw
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Post build analysis.
|
||||
#-------------------------------------------------------------------
|
||||
timing: application_fpga.asc $(P)/data/$(PIN_FILE)
|
||||
$(ICESTORM_PATH)icetime -c 12 -tmd up5k -P sg48 -p $(P)/data/$(PIN_FILE) -t $<
|
||||
|
||||
view: tb_application_fpga_vcd
|
||||
gtkwave $< application_fpga.gtkw
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Cleanup.
|
||||
#-------------------------------------------------------------------
|
||||
clean: clean_fw
|
||||
rm -f bram_fw.hex
|
||||
rm -f synth.{log,v,json} route.v application_fpga.{asc,bin,vcd} application_fpga_testfw.bin
|
||||
rm -f tb_application_fpga.vvp synth_tb.vvp route_tb.vvp
|
||||
rm -f *.vcd
|
||||
rm -rf verilated
|
||||
rm -f tools/tpt/*.hex
|
||||
rm -rf tools/tpt/__pycache__
|
||||
.PHONY: clean
|
||||
|
||||
clean_fw:
|
||||
rm -f firmware.{elf,elf.map,bin,hex}
|
||||
rm -f $(FIRMWARE_OBJS)
|
||||
rm -f testfw.{elf,elf.map,bin,hex}
|
||||
rm -f $(TESTFW_OBJS)
|
||||
.PHONY: clean_fw
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Display info about targets.
|
||||
#-------------------------------------------------------------------
|
||||
help:
|
||||
@echo ""
|
||||
@echo "Build system for application_fpga FPGA design and firmware."
|
||||
@echo ""
|
||||
@echo "Supported targets:"
|
||||
@echo "------------------"
|
||||
@echo "all Build all targets."
|
||||
@echo "firmware.elf Build firmware ELF file."
|
||||
@echo "firmware.hex Build firmware converted to hex, to be included in bitstream."
|
||||
@echo "bram_fw.hex Build a fake BRAM file that will be filled in later after place-n-route."
|
||||
@echo "verilator Build Verilator simulation program"
|
||||
@echo "lint Run lint on Verilog source files."
|
||||
@echo "prog_flash Program device flash with FGPA bitstream including firmware (using the RPi Pico-based programmer)."
|
||||
@echo "prog_flash_testfw Program device flash as above, but with testfw."
|
||||
@echo "clean Delete all generated files."
|
||||
@echo "clean_fw Delete only generated files for firmware. Useful for fw devs."
|
||||
|
||||
#=======================================================================
|
||||
# EOF Makefile
|
||||
#=======================================================================
|
4
hw/application_fpga/core/mta1/README.md
Normal file
4
hw/application_fpga/core/mta1/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# mta1
|
||||
|
||||
## Introduction
|
||||
Top level core that provides chip info, debug support and chip level control.
|
326
hw/application_fpga/core/mta1/rtl/mta1.v
Normal file
326
hw/application_fpga/core/mta1/rtl/mta1.v
Normal file
|
@ -0,0 +1,326 @@
|
|||
//======================================================================
|
||||
//
|
||||
// mta1.v
|
||||
// ------
|
||||
// Top level information, debug and control core for the mta1 design.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module mta1(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
output wire fw_app_mode,
|
||||
|
||||
output wire led_r,
|
||||
output wire led_g,
|
||||
output wire led_b,
|
||||
|
||||
input wire gpio1,
|
||||
input wire gpio2,
|
||||
output wire gpio3,
|
||||
output wire gpio4,
|
||||
|
||||
input wire cs,
|
||||
input wire we,
|
||||
|
||||
input wire [7 : 0] address,
|
||||
input wire [31 : 0] write_data,
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_SWITCH_APP = 8'h08;
|
||||
|
||||
localparam ADDR_LED = 8'h09;
|
||||
localparam LED_R_BIT = 2;
|
||||
localparam LED_G_BIT = 1;
|
||||
localparam LED_B_BIT = 0;
|
||||
|
||||
localparam ADDR_GPIO = 8'h0a;
|
||||
localparam GPIO1_BIT = 0;
|
||||
localparam GPIO2_BIT = 1;
|
||||
localparam GPIO3_BIT = 2;
|
||||
localparam GPIO4_BIT = 3;
|
||||
|
||||
localparam ADDR_APP_START = 8'h0c;
|
||||
localparam ADDR_APP_SIZE = 8'h0d;
|
||||
|
||||
localparam ADDR_DEBUG = 8'h10;
|
||||
|
||||
localparam ADDR_CDI_FIRST = 8'h20;
|
||||
localparam ADDR_CDI_LAST = 8'h27;
|
||||
|
||||
localparam ADDR_UDI_FIRST = 8'h30;
|
||||
localparam ADDR_UDI_LAST = 8'h31;
|
||||
|
||||
localparam MTA1_NAME0 = 32'h6d746131; // "mta1"
|
||||
localparam MTA1_NAME1 = 32'h6d6b6466; // "mkdf"
|
||||
localparam MTA1_VERSION = 32'h00000004;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] cdi_mem [0 : 7];
|
||||
reg [31 : 0] cdi_mem_we;
|
||||
|
||||
reg [31 : 0] udi_mem [0 : 1];
|
||||
initial $readmemh(`UDI_HEX, udi_mem);
|
||||
|
||||
reg switch_app_reg;
|
||||
reg switch_app_we;
|
||||
|
||||
reg [2 : 0] led_reg;
|
||||
reg led_we;
|
||||
|
||||
reg [1 : 0] gpio1_reg;
|
||||
reg [1 : 0] gpio2_reg;
|
||||
reg gpio3_reg;
|
||||
reg gpio3_we;
|
||||
reg gpio4_reg;
|
||||
reg gpio4_we;
|
||||
|
||||
reg [31 : 0] app_start_reg;
|
||||
reg app_start_we;
|
||||
|
||||
reg [31 : 0] app_size_reg;
|
||||
reg app_size_we;
|
||||
|
||||
reg [31 : 0] debug_reg;
|
||||
reg debug_we;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg [31 : 0] tmp_read_data;
|
||||
reg tmp_ready;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = tmp_read_data;
|
||||
assign ready = tmp_ready;
|
||||
|
||||
assign fw_app_mode = switch_app_reg;
|
||||
|
||||
assign gpio3 = gpio3_reg;
|
||||
assign gpio4 = gpio4_reg;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Module instance.
|
||||
//----------------------------------------------------------------
|
||||
SB_RGBA_DRV #(
|
||||
.CURRENT_MODE("0b1"), // half-current mode
|
||||
.RGB0_CURRENT("0b000001"), // 2 mA
|
||||
.RGB1_CURRENT("0b000001"), // 2 mA
|
||||
.RGB2_CURRENT("0b000001") // 2 mA
|
||||
) RGBA_DRV (
|
||||
.RGB0(led_r),
|
||||
.RGB1(led_g),
|
||||
.RGB2(led_b),
|
||||
.RGBLEDEN(1'h1),
|
||||
.RGB0PWM(led_reg[LED_R_BIT]),
|
||||
.RGB1PWM(led_reg[LED_G_BIT]),
|
||||
.RGB2PWM(led_reg[LED_B_BIT]),
|
||||
.CURREN(1'b1)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin : reg_update
|
||||
if (!reset_n) begin
|
||||
switch_app_reg <= 1'h0;
|
||||
led_reg <= 3'h6;
|
||||
gpio1_reg <= 2'h0;
|
||||
gpio2_reg <= 2'h0;
|
||||
gpio3_reg <= 1'h0;
|
||||
gpio4_reg <= 1'h0;
|
||||
app_start_reg <= 32'h0;
|
||||
app_size_reg <= 32'h0;
|
||||
debug_reg <= 32'h0;
|
||||
cdi_mem[0] <= 32'h0;
|
||||
cdi_mem[1] <= 32'h0;
|
||||
cdi_mem[2] <= 32'h0;
|
||||
cdi_mem[3] <= 32'h0;
|
||||
cdi_mem[4] <= 32'h0;
|
||||
cdi_mem[5] <= 32'h0;
|
||||
cdi_mem[6] <= 32'h0;
|
||||
cdi_mem[7] <= 32'h0;
|
||||
end
|
||||
|
||||
else begin
|
||||
gpio1_reg[0] <= gpio1;
|
||||
gpio1_reg[1] <= gpio1_reg[0];
|
||||
|
||||
gpio2_reg[0] <= gpio2;
|
||||
gpio2_reg[1] <= gpio2_reg[0];
|
||||
|
||||
if (switch_app_we) begin
|
||||
switch_app_reg <= 1'h1;
|
||||
end
|
||||
|
||||
if (led_we) begin
|
||||
led_reg <= write_data[2 : 0];
|
||||
end
|
||||
|
||||
if (gpio3_we) begin
|
||||
gpio3_reg <= write_data[GPIO3_BIT];
|
||||
end
|
||||
|
||||
if (gpio4_we) begin
|
||||
gpio4_reg <= write_data[GPIO4_BIT];
|
||||
end
|
||||
|
||||
if (app_start_we) begin
|
||||
app_start_reg <= write_data;
|
||||
end
|
||||
|
||||
if (app_size_we) begin
|
||||
app_size_reg <= write_data;
|
||||
end
|
||||
|
||||
if (debug_we) begin
|
||||
debug_reg <= write_data;
|
||||
end
|
||||
|
||||
if (cdi_mem_we) begin
|
||||
cdi_mem[address[2 : 0]] <= write_data;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// api
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : api
|
||||
switch_app_we = 1'h0;
|
||||
led_we = 1'h0;
|
||||
gpio3_we = 1'h0;
|
||||
gpio4_we = 1'h0;
|
||||
app_start_we = 1'h0;
|
||||
app_size_we = 1'h0;
|
||||
debug_we = 1'h0;
|
||||
cdi_mem_we = 1'h0;
|
||||
cdi_mem_we = 1'h0;
|
||||
tmp_read_data = 32'h00000000;
|
||||
tmp_ready = 1'h0;
|
||||
|
||||
if (cs) begin
|
||||
tmp_ready = 1'h1;
|
||||
if (we) begin
|
||||
if (address == ADDR_SWITCH_APP) begin
|
||||
switch_app_we = 1'h1;
|
||||
end
|
||||
|
||||
if (address == ADDR_LED) begin
|
||||
led_we = 1'h1;
|
||||
end
|
||||
|
||||
if (address == ADDR_GPIO) begin
|
||||
gpio3_we = 1'h1;
|
||||
gpio4_we = 1'h1;
|
||||
end
|
||||
|
||||
if (address == ADDR_APP_START) begin
|
||||
if (!switch_app_reg) begin
|
||||
app_start_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
if (address == ADDR_APP_SIZE) begin
|
||||
if (!switch_app_reg) begin
|
||||
app_size_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
if (address == ADDR_DEBUG) begin
|
||||
debug_we = 1'h1;
|
||||
end
|
||||
|
||||
if ((address >= ADDR_CDI_FIRST) && (address <= ADDR_CDI_LAST)) begin
|
||||
if (!switch_app_reg) begin
|
||||
cdi_mem_we = 1'h1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else begin
|
||||
if (address == ADDR_NAME0) begin
|
||||
tmp_read_data = MTA1_NAME0;
|
||||
end
|
||||
|
||||
if (address == ADDR_NAME1) begin
|
||||
tmp_read_data = MTA1_NAME1;
|
||||
end
|
||||
|
||||
if (address == ADDR_VERSION) begin
|
||||
tmp_read_data = MTA1_VERSION;
|
||||
end
|
||||
|
||||
if (address == ADDR_SWITCH_APP) begin
|
||||
tmp_read_data = {32{switch_app_reg}};
|
||||
end
|
||||
|
||||
if (address == ADDR_LED) begin
|
||||
tmp_read_data = {29'h0, led_reg};
|
||||
end
|
||||
|
||||
if (address == ADDR_GPIO) begin
|
||||
tmp_read_data = {28'h0, gpio4_reg, gpio3_reg,
|
||||
gpio2_reg[1], gpio1_reg[1]};
|
||||
end
|
||||
|
||||
if (address == ADDR_APP_START) begin
|
||||
tmp_read_data = app_start_reg;
|
||||
end
|
||||
|
||||
if (address == ADDR_APP_SIZE) begin
|
||||
tmp_read_data = app_size_reg;
|
||||
end
|
||||
|
||||
if (address == ADDR_DEBUG) begin
|
||||
tmp_read_data = debug_reg;
|
||||
end
|
||||
|
||||
if ((address >= ADDR_CDI_FIRST) && (address <= ADDR_CDI_LAST)) begin
|
||||
tmp_read_data = cdi_mem[address[2 : 0]];
|
||||
end
|
||||
|
||||
if ((address >= ADDR_UDI_FIRST) && (address <= ADDR_UDI_LAST)) begin
|
||||
tmp_read_data = udi_mem[address[0]];
|
||||
end
|
||||
end
|
||||
end
|
||||
end // api
|
||||
|
||||
endmodule // mta1
|
||||
|
||||
//======================================================================
|
||||
// EOF mta1.v
|
||||
//======================================================================
|
15
hw/application_fpga/core/picorv32/LICENSE
Normal file
15
hw/application_fpga/core/picorv32/LICENSE
Normal file
|
@ -0,0 +1,15 @@
|
|||
ISC License
|
||||
|
||||
Copyright (C) 2015 - 2021 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
4
hw/application_fpga/core/picorv32/README.md
Normal file
4
hw/application_fpga/core/picorv32/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# PicoRV32 - A Size-Optimized RISC-V CPU
|
||||
|
||||
This is a local copy of the
|
||||
[PicoRV32](https://github.com/cliffordwolf/picorv32) RISC-V CPU core.
|
3044
hw/application_fpga/core/picorv32/rtl/picorv32.v
Normal file
3044
hw/application_fpga/core/picorv32/rtl/picorv32.v
Normal file
File diff suppressed because it is too large
Load diff
5
hw/application_fpga/core/timer/README.md
Normal file
5
hw/application_fpga/core/timer/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# timer
|
||||
A simple timer with prescaler written in Verilog.
|
||||
|
||||
## Introduction
|
||||
This core implements a simple timer with a prescaler. The purpose of the prescaler is to more easily time durations rather than cycles. If for example setting the timer to the clock frequency, the timer can cound seconds.
|
194
hw/application_fpga/core/timer/rtl/timer.v
Normal file
194
hw/application_fpga/core/timer/rtl/timer.v
Normal file
|
@ -0,0 +1,194 @@
|
|||
//======================================================================
|
||||
//
|
||||
// timer.v
|
||||
// --------
|
||||
// Top level wrapper for the timer core.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module timer(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire cs,
|
||||
input wire we,
|
||||
|
||||
input wire [7 : 0] address,
|
||||
input wire [31 : 0] write_data,
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_CTRL = 8'h08;
|
||||
localparam CTRL_START_BIT = 0;
|
||||
localparam CTRL_STOP_BIT = 1;
|
||||
|
||||
localparam ADDR_STATUS = 8'h09;
|
||||
localparam STATUS_READY_BIT = 0;
|
||||
|
||||
localparam ADDR_PRESCALER = 8'h0a;
|
||||
localparam ADDR_TIMER = 8'h0b;
|
||||
|
||||
localparam CORE_NAME0 = 32'h74696d65; // "time"
|
||||
localparam CORE_NAME1 = 32'h72202020; // "r "
|
||||
localparam CORE_VERSION = 32'h00000003;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] prescaler_reg;
|
||||
reg prescaler_we;
|
||||
|
||||
reg [31 : 0] timer_reg;
|
||||
reg timer_we;
|
||||
|
||||
reg start_reg;
|
||||
reg start_new;
|
||||
|
||||
reg stop_reg;
|
||||
reg stop_new;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] tmp_read_data;
|
||||
reg tmp_ready;
|
||||
|
||||
wire core_ready;
|
||||
wire [31 : 0] core_curr_prescaler;
|
||||
wire [31 : 0] core_curr_timer;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = tmp_read_data;
|
||||
assign ready = tmp_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// core instantiation.
|
||||
//----------------------------------------------------------------
|
||||
timer_core core(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.prescaler_value(prescaler_reg),
|
||||
.timer_value(timer_reg),
|
||||
.start(start_reg),
|
||||
.stop(stop_reg),
|
||||
.curr_prescaler(core_curr_prescaler),
|
||||
.curr_timer(core_curr_timer),
|
||||
.ready(core_ready)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin : reg_update
|
||||
if (!reset_n) begin
|
||||
start_reg <= 1'h0;
|
||||
stop_reg <= 1'h0;
|
||||
prescaler_reg <= 32'h0;
|
||||
timer_reg <= 32'h0;
|
||||
end
|
||||
|
||||
else begin
|
||||
start_reg <= start_new;
|
||||
stop_reg <= stop_new;
|
||||
|
||||
if (prescaler_we) begin
|
||||
prescaler_reg <= write_data;
|
||||
end
|
||||
|
||||
if (timer_we) begin
|
||||
timer_reg <= write_data;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// api
|
||||
//
|
||||
// The interface command decoding logic.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : api
|
||||
start_new = 1'h0;
|
||||
stop_new = 1'h0;
|
||||
prescaler_we = 1'h0;
|
||||
timer_we = 1'h0;
|
||||
tmp_read_data = 32'h0;
|
||||
tmp_ready = 1'h0;
|
||||
|
||||
if (cs) begin
|
||||
tmp_ready = 1'h1;
|
||||
|
||||
if (we) begin
|
||||
if (address == ADDR_CTRL) begin
|
||||
start_new = write_data[CTRL_START_BIT];
|
||||
stop_new = write_data[CTRL_STOP_BIT];
|
||||
end
|
||||
|
||||
if (core_ready) begin
|
||||
if (address == ADDR_PRESCALER) begin
|
||||
prescaler_we = 1'h1;
|
||||
end
|
||||
|
||||
if (address == ADDR_TIMER) begin
|
||||
timer_we = 1'h1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else begin
|
||||
if (address == ADDR_NAME0) begin
|
||||
tmp_read_data = CORE_NAME0;
|
||||
end
|
||||
|
||||
if (address == ADDR_NAME1) begin
|
||||
tmp_read_data = CORE_NAME1;
|
||||
end
|
||||
|
||||
if (address == ADDR_VERSION) begin
|
||||
tmp_read_data = CORE_VERSION;
|
||||
end
|
||||
|
||||
if (address == ADDR_STATUS) begin
|
||||
tmp_read_data = {31'h0, core_ready};
|
||||
end
|
||||
|
||||
if (address == ADDR_PRESCALER) begin
|
||||
tmp_read_data = core_curr_prescaler;
|
||||
end
|
||||
|
||||
if (address == ADDR_TIMER) begin
|
||||
tmp_read_data = core_curr_timer;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // addr_decoder
|
||||
endmodule // timer
|
||||
|
||||
//======================================================================
|
||||
// EOF timer.v
|
||||
//======================================================================
|
225
hw/application_fpga/core/timer/rtl/timer_core.v
Normal file
225
hw/application_fpga/core/timer/rtl/timer_core.v
Normal file
|
@ -0,0 +1,225 @@
|
|||
//======================================================================
|
||||
//
|
||||
// timer_core.v
|
||||
// ------------
|
||||
// timer core.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module timer_core(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire [31 : 0] prescaler_value,
|
||||
input wire [31 : 0] timer_value,
|
||||
input wire start,
|
||||
input wire stop,
|
||||
|
||||
output wire [31 : 0] curr_prescaler,
|
||||
output wire [31 : 0] curr_timer,
|
||||
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam CTRL_IDLE = 2'h0;
|
||||
localparam CTRL_PRESCALER = 2'h1;
|
||||
localparam CTRL_TIMER = 2'h2;
|
||||
localparam CTRL_DONE = 2'h3;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg ready_reg;
|
||||
reg ready_new;
|
||||
reg ready_we;
|
||||
|
||||
reg [31 : 0] prescaler_reg;
|
||||
reg [31 : 0] prescaler_new;
|
||||
reg prescaler_we;
|
||||
reg prescaler_set;
|
||||
reg prescaler_dec;
|
||||
|
||||
reg [31 : 0] timer_reg;
|
||||
reg [31 : 0] timer_new;
|
||||
reg timer_we;
|
||||
reg timer_set;
|
||||
reg timer_dec;
|
||||
|
||||
reg [1 : 0] core_ctrl_reg;
|
||||
reg [1 : 0] core_ctrl_new;
|
||||
reg core_ctrl_we;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign curr_prescaler = prescaler_reg;
|
||||
assign curr_timer = timer_reg;
|
||||
assign ready = ready_reg;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin: reg_update
|
||||
if (!reset_n)
|
||||
begin
|
||||
ready_reg <= 1'h1;
|
||||
prescaler_reg <= 32'h0;
|
||||
timer_reg <= 32'h0;
|
||||
core_ctrl_reg <= CTRL_IDLE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (ready_we) begin
|
||||
ready_reg <= ready_new;
|
||||
end
|
||||
|
||||
if (prescaler_we) begin
|
||||
prescaler_reg <= prescaler_new;
|
||||
end
|
||||
|
||||
if (timer_we) begin
|
||||
timer_reg <= timer_new;
|
||||
end
|
||||
|
||||
if (core_ctrl_we) begin
|
||||
core_ctrl_reg <= core_ctrl_new;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// prescaler_ctr
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : prescaler_ctr
|
||||
prescaler_new = 32'h0;
|
||||
prescaler_we = 1'h0;
|
||||
|
||||
if (prescaler_set) begin
|
||||
prescaler_new = prescaler_value;
|
||||
prescaler_we = 1'h1;
|
||||
end
|
||||
else if (prescaler_dec) begin
|
||||
prescaler_new = prescaler_reg - 1'h1;
|
||||
prescaler_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// timer_ctr
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : timer_ctr
|
||||
timer_new = 32'h0;
|
||||
timer_we = 1'h0;
|
||||
|
||||
if (timer_set) begin
|
||||
timer_new = timer_value;
|
||||
timer_we = 1'h1;
|
||||
end
|
||||
else if (timer_dec) begin
|
||||
timer_new = timer_reg - 1'h1;
|
||||
timer_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Core control FSM.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : core_ctrl
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h0;
|
||||
prescaler_set = 1'h0;
|
||||
prescaler_dec = 1'h0;
|
||||
timer_set = 1'h0;
|
||||
timer_dec = 1'h0;
|
||||
core_ctrl_new = CTRL_IDLE;
|
||||
core_ctrl_we = 1'h0;
|
||||
|
||||
case (core_ctrl_reg)
|
||||
CTRL_IDLE: begin
|
||||
if (start)
|
||||
begin
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h1;
|
||||
prescaler_set = 1'h1;
|
||||
timer_set = 1'h1;
|
||||
core_ctrl_new = CTRL_PRESCALER;
|
||||
core_ctrl_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
CTRL_PRESCALER: begin
|
||||
if (stop) begin
|
||||
core_ctrl_new = CTRL_DONE;
|
||||
core_ctrl_we = 1'h1;
|
||||
end
|
||||
else begin
|
||||
if (prescaler_reg == 0) begin
|
||||
core_ctrl_new = CTRL_TIMER;
|
||||
core_ctrl_we = 1'h1;
|
||||
end
|
||||
else begin
|
||||
prescaler_dec = 1'h1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
CTRL_TIMER: begin
|
||||
if (stop) begin
|
||||
core_ctrl_new = CTRL_DONE;
|
||||
core_ctrl_we = 1'h1;
|
||||
end
|
||||
else begin
|
||||
if (timer_reg == 0) begin
|
||||
core_ctrl_new = CTRL_DONE;
|
||||
core_ctrl_we = 1'h1;
|
||||
end
|
||||
else begin
|
||||
prescaler_set = 1'h1;
|
||||
timer_dec = 1'h1;
|
||||
core_ctrl_new = CTRL_PRESCALER;
|
||||
core_ctrl_we = 1'h1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
CTRL_DONE: begin
|
||||
ready_new = 1'h1;
|
||||
ready_we = 1'h1;
|
||||
core_ctrl_new = CTRL_IDLE;
|
||||
core_ctrl_we = 1'h1;
|
||||
end
|
||||
|
||||
default: begin
|
||||
end
|
||||
endcase // case (core_ctrl_reg)
|
||||
end // core_ctrl
|
||||
|
||||
endmodule // timer_core
|
||||
|
||||
//======================================================================
|
||||
// EOF timer_core.v
|
||||
//======================================================================
|
293
hw/application_fpga/core/timer/tb/tb_timer.v
Normal file
293
hw/application_fpga/core/timer/tb/tb_timer.v
Normal file
|
@ -0,0 +1,293 @@
|
|||
//======================================================================
|
||||
//
|
||||
// tb_timer.v
|
||||
// -----------
|
||||
// Testbench for the timer top level wrapper.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module tb_timer();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
parameter DEBUG = 0;
|
||||
parameter DUMP_WAIT = 0;
|
||||
|
||||
parameter CLK_HALF_PERIOD = 1;
|
||||
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
|
||||
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_CTRL = 8'h08;
|
||||
localparam CTRL_NEXT_BIT = 0;
|
||||
|
||||
localparam ADDR_STATUS = 8'h09;
|
||||
localparam STATUS_READY_BIT = 0;
|
||||
|
||||
localparam ADDR_CONFIG = 8'h0a;
|
||||
localparam CONFIG_ENCDEC_BIT = 0;
|
||||
|
||||
localparam ADDR_KEY0 = 8'h10;
|
||||
localparam ADDR_KEY1 = 8'h11;
|
||||
localparam ADDR_KEY2 = 8'h12;
|
||||
localparam ADDR_KEY3 = 8'h13;
|
||||
|
||||
localparam ADDR_BLOCK0 = 8'h20;
|
||||
localparam ADDR_BLOCK1 = 8'h21;
|
||||
|
||||
localparam ADDR_RESULT0 = 8'h30;
|
||||
localparam ADDR_RESULT1 = 8'h31;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Register and Wire declarations.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] cycle_ctr;
|
||||
reg [31 : 0] error_ctr;
|
||||
reg [31 : 0] tc_ctr;
|
||||
reg tb_monitor;
|
||||
|
||||
reg tb_clk;
|
||||
reg tb_reset_n;
|
||||
reg tb_cs;
|
||||
reg tb_we;
|
||||
reg [7 : 0] tb_address;
|
||||
reg [31 : 0] tb_write_data;
|
||||
wire [31 : 0] tb_read_data;
|
||||
|
||||
reg [31 : 0] read_data;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Device Under Test.
|
||||
//----------------------------------------------------------------
|
||||
timer dut(
|
||||
.clk(tb_clk),
|
||||
.reset_n(tb_reset_n),
|
||||
|
||||
.cs(tb_cs),
|
||||
.we(tb_we),
|
||||
|
||||
.address(tb_address),
|
||||
.write_data(tb_write_data),
|
||||
.read_data(tb_read_data)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// clk_gen
|
||||
//
|
||||
// Always running clock generator process.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : clk_gen
|
||||
#CLK_HALF_PERIOD;
|
||||
tb_clk = !tb_clk;
|
||||
end // clk_gen
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// sys_monitor()
|
||||
//
|
||||
// An always running process that creates a cycle counter and
|
||||
// conditionally displays information about the DUT.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : sys_monitor
|
||||
cycle_ctr = cycle_ctr + 1;
|
||||
#(CLK_PERIOD);
|
||||
if (tb_monitor)
|
||||
begin
|
||||
dump_dut_state();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// dump_dut_state()
|
||||
//
|
||||
// Dump the state of the dump when needed.
|
||||
//----------------------------------------------------------------
|
||||
task dump_dut_state;
|
||||
begin
|
||||
$display("State of DUT");
|
||||
$display("------------");
|
||||
$display("Cycle: %08d", cycle_ctr);
|
||||
$display("");
|
||||
end
|
||||
endtask // dump_dut_state
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reset_dut()
|
||||
//
|
||||
// Toggle reset to put the DUT into a well known state.
|
||||
//----------------------------------------------------------------
|
||||
task reset_dut;
|
||||
begin
|
||||
$display("--- Toggle reset.");
|
||||
tb_reset_n = 0;
|
||||
#(2 * CLK_PERIOD);
|
||||
tb_reset_n = 1;
|
||||
end
|
||||
endtask // reset_dut
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// display_test_result()
|
||||
//
|
||||
// Display the accumulated test results.
|
||||
//----------------------------------------------------------------
|
||||
task display_test_result;
|
||||
begin
|
||||
if (error_ctr == 0)
|
||||
begin
|
||||
$display("--- All %02d test cases completed successfully", tc_ctr);
|
||||
end
|
||||
else
|
||||
begin
|
||||
$display("--- %02d tests completed - %02d test cases did not complete successfully.",
|
||||
tc_ctr, error_ctr);
|
||||
end
|
||||
end
|
||||
endtask // display_test_result
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// init_sim()
|
||||
//
|
||||
// Initialize all counters and testbed functionality as well
|
||||
// as setting the DUT inputs to defined values.
|
||||
//----------------------------------------------------------------
|
||||
task init_sim;
|
||||
begin
|
||||
cycle_ctr = 0;
|
||||
error_ctr = 0;
|
||||
tc_ctr = 0;
|
||||
tb_monitor = 0;
|
||||
|
||||
tb_clk = 1'h0;
|
||||
tb_reset_n = 1'h1;
|
||||
tb_cs = 1'h0;
|
||||
tb_we = 1'h0;
|
||||
tb_address = 8'h0;
|
||||
tb_write_data = 32'h0;
|
||||
end
|
||||
endtask // init_sim
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// write_word()
|
||||
//
|
||||
// Write the given word to the DUT using the DUT interface.
|
||||
//----------------------------------------------------------------
|
||||
task write_word(input [11 : 0] address,
|
||||
input [31 : 0] word);
|
||||
begin
|
||||
if (DEBUG)
|
||||
begin
|
||||
$display("--- Writing 0x%08x to 0x%02x.", word, address);
|
||||
$display("");
|
||||
end
|
||||
|
||||
tb_address = address;
|
||||
tb_write_data = word;
|
||||
tb_cs = 1;
|
||||
tb_we = 1;
|
||||
#(2 * CLK_PERIOD);
|
||||
tb_cs = 0;
|
||||
tb_we = 0;
|
||||
end
|
||||
endtask // write_word
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// read_word()
|
||||
//
|
||||
// Read a data word from the given address in the DUT.
|
||||
// the word read will be available in the global variable
|
||||
// read_data.
|
||||
//----------------------------------------------------------------
|
||||
task read_word(input [11 : 0] address);
|
||||
begin
|
||||
tb_address = address;
|
||||
tb_cs = 1;
|
||||
tb_we = 0;
|
||||
#(CLK_PERIOD);
|
||||
read_data = tb_read_data;
|
||||
tb_cs = 0;
|
||||
|
||||
if (DEBUG)
|
||||
begin
|
||||
$display("--- Reading 0x%08x from 0x%02x.", read_data, address);
|
||||
$display("");
|
||||
end
|
||||
end
|
||||
endtask // read_word
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// wait_ready()
|
||||
//
|
||||
// Wait for the ready flag to be set in dut.
|
||||
//----------------------------------------------------------------
|
||||
task wait_ready;
|
||||
begin : wready
|
||||
read_word(ADDR_STATUS);
|
||||
while (read_data == 0)
|
||||
read_word(ADDR_STATUS);
|
||||
end
|
||||
endtask // wait_ready
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// test1()
|
||||
//----------------------------------------------------------------
|
||||
task test1;
|
||||
begin
|
||||
tc_ctr = tc_ctr + 1;
|
||||
|
||||
$display("");
|
||||
$display("--- test1: started.");
|
||||
|
||||
$display("--- test1: completed.");
|
||||
$display("");
|
||||
end
|
||||
endtask // tes1
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// timer_test
|
||||
//----------------------------------------------------------------
|
||||
initial
|
||||
begin : timer_test
|
||||
$display("");
|
||||
$display(" -= Testbench for timer started =-");
|
||||
$display(" =============================");
|
||||
$display("");
|
||||
|
||||
init_sim();
|
||||
reset_dut();
|
||||
test1();
|
||||
|
||||
display_test_result();
|
||||
$display("");
|
||||
$display(" -= Testbench for timer started =-");
|
||||
$display(" =============================");
|
||||
$display("");
|
||||
$finish;
|
||||
end // timer_test
|
||||
endmodule // tb_timer
|
||||
|
||||
//======================================================================
|
||||
// EOF tb_timer.v
|
||||
//======================================================================
|
247
hw/application_fpga/core/timer/tb/tb_timer_core.v
Normal file
247
hw/application_fpga/core/timer/tb/tb_timer_core.v
Normal file
|
@ -0,0 +1,247 @@
|
|||
//======================================================================
|
||||
//
|
||||
// tb_timer_core.v
|
||||
// --------------
|
||||
// Testbench for the timer core.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module tb_timer_core();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
parameter DEBUG = 0;
|
||||
parameter DUMP_WAIT = 0;
|
||||
|
||||
parameter CLK_HALF_PERIOD = 1;
|
||||
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Register and Wire declarations.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] cycle_ctr;
|
||||
reg [31 : 0] error_ctr;
|
||||
reg [31 : 0] tc_ctr;
|
||||
reg tb_monitor;
|
||||
|
||||
reg tb_clk;
|
||||
reg tb_reset_n;
|
||||
reg tb_start;
|
||||
reg tb_stop;
|
||||
reg [31 : 0] tb_prescaler;
|
||||
reg [31 : 0] tb_timer;
|
||||
wire [31 : 0] tb_curr_prescaler;
|
||||
wire [31 : 0] tb_curr_timer;
|
||||
wire tb_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Device Under Test.
|
||||
//----------------------------------------------------------------
|
||||
timer_core dut(
|
||||
.clk(tb_clk),
|
||||
.reset_n(tb_reset_n),
|
||||
.prescaler_value(tb_prescaler),
|
||||
.timer_value(tb_timer),
|
||||
.start(tb_start),
|
||||
.stop(tb_stop),
|
||||
.curr_prescaler(tb_curr_prescaler),
|
||||
.curr_timer(tb_curr_timer),
|
||||
.ready(tb_ready)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// clk_gen
|
||||
//
|
||||
// Always running clock generator process.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : clk_gen
|
||||
#CLK_HALF_PERIOD;
|
||||
tb_clk = !tb_clk;
|
||||
end // clk_gen
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// sys_monitor()
|
||||
//
|
||||
// An always running process that creates a cycle counter and
|
||||
// conditionally displays information about the DUT.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : sys_monitor
|
||||
cycle_ctr = cycle_ctr + 1;
|
||||
#(CLK_PERIOD);
|
||||
if (tb_monitor)
|
||||
begin
|
||||
dump_dut_state();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// dump_dut_state()
|
||||
//
|
||||
// Dump the state of the dump when needed.
|
||||
//----------------------------------------------------------------
|
||||
task dump_dut_state;
|
||||
begin
|
||||
$display("State of DUT");
|
||||
$display("------------");
|
||||
$display("Cycle: %08d", cycle_ctr);
|
||||
$display("");
|
||||
$display("Inputs and outputs:");
|
||||
$display("start: 0x%1x, stop: 0x%1x, ready: 0x%1x",
|
||||
dut.start, dut.stop, dut.ready);
|
||||
$display("prescaler_value: 0x%08x, timer_value: 0x%08x",
|
||||
dut.prescaler_value, dut.timer_value);
|
||||
$display("");
|
||||
$display("Internal state:");
|
||||
$display("prescaler_reg: 0x%08x, prescaler_new: 0x%08x",
|
||||
dut.prescaler_reg, dut.prescaler_new);
|
||||
$display("prescaler_set: 0x%1x, prescaler_dec: 0x%1x",
|
||||
dut.prescaler_set, dut.prescaler_dec);
|
||||
$display("");
|
||||
$display("timer_reg: 0x%08x, timer_new: 0x%08x",
|
||||
dut.timer_reg, dut.timer_new);
|
||||
$display("timer_set: 0x%1x, timer_dec: 0x%1x",
|
||||
dut.timer_set, dut.timer_dec);
|
||||
$display("");
|
||||
$display("core_ctrl_reg: 0x%02x, core_ctrl_new: 0x%02x, core_ctrl_we: 0x%1x",
|
||||
dut.core_ctrl_reg, dut.core_ctrl_new, dut.core_ctrl_we);
|
||||
$display("");
|
||||
$display("");
|
||||
end
|
||||
endtask // dump_dut_state
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reset_dut()
|
||||
//
|
||||
// Toggle reset to put the DUT into a well known state.
|
||||
//----------------------------------------------------------------
|
||||
task reset_dut;
|
||||
begin
|
||||
$display("--- DUT before reset:");
|
||||
dump_dut_state();
|
||||
$display("--- Toggling reset.");
|
||||
tb_reset_n = 0;
|
||||
#(2 * CLK_PERIOD);
|
||||
tb_reset_n = 1;
|
||||
$display("--- DUT after reset:");
|
||||
dump_dut_state();
|
||||
end
|
||||
endtask // reset_dut
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// wait_ready()
|
||||
//
|
||||
// Wait for the ready flag in the dut to be set.
|
||||
//
|
||||
// Note: It is the callers responsibility to call the function
|
||||
// when the dut is actively processing and will in fact at some
|
||||
// point set the flag.
|
||||
//----------------------------------------------------------------
|
||||
task wait_ready;
|
||||
begin
|
||||
#(2 * CLK_PERIOD);
|
||||
while (!tb_ready)
|
||||
begin
|
||||
#(CLK_PERIOD);
|
||||
if (DUMP_WAIT)
|
||||
begin
|
||||
dump_dut_state();
|
||||
end
|
||||
end
|
||||
end
|
||||
endtask // wait_ready
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// init_sim()
|
||||
//
|
||||
// Initialize all counters and testbed functionality as well
|
||||
// as setting the DUT inputs to defined values.
|
||||
//----------------------------------------------------------------
|
||||
task init_sim;
|
||||
begin
|
||||
cycle_ctr = 0;
|
||||
error_ctr = 0;
|
||||
tc_ctr = 0;
|
||||
tb_monitor = 0;
|
||||
|
||||
tb_clk = 0;
|
||||
tb_reset_n = 1;
|
||||
|
||||
tb_start = 1'h0;
|
||||
tb_stop = 1'h0;
|
||||
tb_prescaler = 32'h0;
|
||||
tb_timer = 32'h0;
|
||||
end
|
||||
endtask // init_sim
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// test()
|
||||
// Runs an encipher, decipher test with given key and plaintext
|
||||
// The generated ciphertext is verified with the given ciphertet.
|
||||
// The generated plaintxt is also verified against the
|
||||
// given plaintext.
|
||||
//----------------------------------------------------------------
|
||||
task test1;
|
||||
begin
|
||||
tc_ctr = tc_ctr + 1;
|
||||
tb_monitor = 1;
|
||||
|
||||
$display("--- test1 started.");
|
||||
dump_dut_state();
|
||||
tb_prescaler = 32'h6;
|
||||
tb_timer = 32'h9;
|
||||
#(CLK_PERIOD);
|
||||
tb_start = 1'h1;
|
||||
#(CLK_PERIOD);
|
||||
tb_start = 1'h0;
|
||||
wait_ready();
|
||||
#(CLK_PERIOD);
|
||||
tb_monitor = 0;
|
||||
$display("--- test1 completed.");
|
||||
$display("");
|
||||
end
|
||||
endtask // test1
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// timer_core_test
|
||||
//
|
||||
// Test vectors from:
|
||||
//----------------------------------------------------------------
|
||||
initial
|
||||
begin : timer_core_test
|
||||
$display("--- Simulation of TIMER core started.");
|
||||
$display("");
|
||||
|
||||
init_sim();
|
||||
reset_dut();
|
||||
|
||||
test1();
|
||||
|
||||
$display("");
|
||||
$display("--- Simulation of timer core completed.");
|
||||
$finish;
|
||||
end // timer_core_test
|
||||
endmodule // tb_timer_core
|
||||
|
||||
//======================================================================
|
||||
// EOF tb_timer_core.v
|
||||
//======================================================================
|
75
hw/application_fpga/core/timer/toolruns/Makefile
Executable file
75
hw/application_fpga/core/timer/toolruns/Makefile
Executable file
|
@ -0,0 +1,75 @@
|
|||
#===================================================================
|
||||
#
|
||||
# Makefile
|
||||
# --------
|
||||
# Makefile for building the timer core and top simulations.
|
||||
#
|
||||
#
|
||||
# Author: Joachim Strombergson
|
||||
# Copyright (C) 2022 - Tillitis AB
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
#===================================================================
|
||||
|
||||
CORE_SRC=../rtl/timer_core.v
|
||||
TB_CORE_SRC =../tb/tb_timer_core.v
|
||||
|
||||
TOP_SRC=../rtl/timer.v $(CORE_SRC)
|
||||
TB_TOP_SRC =../tb/tb_timer.v
|
||||
|
||||
CC = iverilog
|
||||
CC_FLAGS = -Wall
|
||||
|
||||
LINT = verilator
|
||||
LINT_FLAGS = +1364-2001ext+ --lint-only -Wall -Wno-fatal -Wno-DECLFILENAME
|
||||
|
||||
|
||||
all: top.sim core.sim
|
||||
|
||||
|
||||
top.sim: $(TB_TOP_SRC) $(TOP_SRC)
|
||||
$(CC) $(CC_FLAGS) -o top.sim $(TB_TOP_SRC) $(TOP_SRC)
|
||||
|
||||
|
||||
core.sim: $(TB_CORE_SRC) $(CORE_SRC)
|
||||
$(CC) $(CC_FLAGS) -o core.sim $(TB_CORE_SRC) $(CORE_SRC)
|
||||
|
||||
|
||||
sim-top: top.sim
|
||||
./top.sim
|
||||
|
||||
|
||||
sim-core: core.sim
|
||||
./core.sim
|
||||
|
||||
|
||||
lint-core: $(CORE_SRC)
|
||||
$(LINT) $(LINT_FLAGS) $(CORE_SRC)
|
||||
|
||||
|
||||
lint-top: $(TOP_SRC)
|
||||
$(LINT) $(LINT_FLAGS) $(TOP_SRC)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f top.sim
|
||||
rm -f core.sim
|
||||
|
||||
|
||||
help:
|
||||
@echo "Build system for simulation of Prince core"
|
||||
@echo ""
|
||||
@echo "Supported targets:"
|
||||
@echo "------------------"
|
||||
@echo "all: Build all simulation targets."
|
||||
@echo "top.sim: Build top level simulation target."
|
||||
@echo "core.sim: Build core level simulation target."
|
||||
@echo "sim-top: Run top level simulation."
|
||||
@echo "sim-core: Run core level simulation."
|
||||
@echo "lint-core: Lint core rtl source files."
|
||||
@echo "lint-core: Lint top rtl source files."
|
||||
@echo "clean: Delete all built files."
|
||||
|
||||
#===================================================================
|
||||
# EOF Makefile
|
||||
#===================================================================
|
5
hw/application_fpga/core/touch_sense/README.md
Normal file
5
hw/application_fpga/core/touch_sense/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# touch_sense
|
||||
Core that handles touch senor events and provides them via an API.
|
||||
|
||||
## Introduction
|
||||
This core implements a touch sensor handler. The core detects and holds events for SW to read. The user must lift the finger between touch events.
|
211
hw/application_fpga/core/touch_sense/rtl/touch_sense.v
Normal file
211
hw/application_fpga/core/touch_sense/rtl/touch_sense.v
Normal file
|
@ -0,0 +1,211 @@
|
|||
//======================================================================
|
||||
//
|
||||
// touch_sense.v
|
||||
// -------------
|
||||
// Touch sensor handler.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module touch_sense(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire touch_event,
|
||||
|
||||
input wire cs,
|
||||
input wire we,
|
||||
|
||||
input wire [7 : 0] address,
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_STATUS = 8'h09;
|
||||
localparam STATUS_EVENT_BIT = 0;
|
||||
|
||||
localparam CORE_NAME0 = 32'h745f7365; // "t_se"
|
||||
localparam CORE_NAME1 = 32'h6e736520; // "nse "
|
||||
localparam CORE_VERSION = 32'h00000001;
|
||||
|
||||
localparam CTRL_IDLE = 2'h0;
|
||||
localparam CTRL_EVENT = 2'h1;
|
||||
localparam CTRL_WAIT = 2'h2;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg touch_event_sample0_reg;
|
||||
reg touch_event_sample1_reg;
|
||||
|
||||
reg touch_event_reg;
|
||||
reg touch_event_new;
|
||||
reg touch_event_set;
|
||||
reg touch_event_rst;
|
||||
reg touch_event_we;
|
||||
|
||||
reg [1 : 0] touch_sense_ctrl_reg;
|
||||
reg [1 : 0] touch_sense_ctrl_new;
|
||||
reg touch_sense_ctrl_we;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] tmp_read_data;
|
||||
reg [31 : 0] tmp_ready;
|
||||
reg api_clear_event;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = tmp_read_data;
|
||||
assign ready = tmp_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin : reg_update
|
||||
if (!reset_n) begin
|
||||
touch_sense_ctrl_reg <= CTRL_IDLE;
|
||||
touch_event_sample0_reg <= 1'h0;
|
||||
touch_event_sample1_reg <= 1'h0;
|
||||
touch_event_reg <= 1'h0;
|
||||
end
|
||||
|
||||
else begin
|
||||
touch_event_sample0_reg <= touch_event;
|
||||
touch_event_sample1_reg <= touch_event_sample0_reg;
|
||||
|
||||
if (touch_event_we) begin
|
||||
touch_event_reg <= touch_event_new;
|
||||
end
|
||||
|
||||
if (touch_sense_ctrl_we) begin
|
||||
touch_sense_ctrl_reg <= touch_sense_ctrl_new;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// api
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : api
|
||||
api_clear_event = 1'h0;
|
||||
tmp_read_data = 32'h0;
|
||||
tmp_ready = 1'h0;
|
||||
|
||||
if (cs) begin
|
||||
tmp_ready = 1'h1;
|
||||
|
||||
if (we) begin
|
||||
if (address == ADDR_STATUS) begin
|
||||
api_clear_event = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
else begin
|
||||
if (address == ADDR_NAME0) begin
|
||||
tmp_read_data = CORE_NAME0;
|
||||
end
|
||||
|
||||
if (address == ADDR_NAME1) begin
|
||||
tmp_read_data = CORE_NAME1;
|
||||
end
|
||||
|
||||
if (address == ADDR_VERSION) begin
|
||||
tmp_read_data = CORE_VERSION;
|
||||
end
|
||||
|
||||
if (address == ADDR_STATUS) begin
|
||||
tmp_read_data[STATUS_EVENT_BIT] = touch_event_reg;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // api
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// touch_event_reg_logic
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : touch_event_reg_logic
|
||||
touch_event_new = 1'h0;
|
||||
touch_event_we = 1'h0;
|
||||
|
||||
if (touch_event_set) begin
|
||||
touch_event_new = 1'h1;
|
||||
touch_event_we = 1'h1;
|
||||
end
|
||||
|
||||
else if (touch_event_rst) begin
|
||||
touch_event_new = 1'h0;
|
||||
touch_event_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// touch_sense_ctrl
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : touch_sense_ctrl
|
||||
touch_event_set = 1'h0;
|
||||
touch_event_rst = 1'h0;
|
||||
touch_sense_ctrl_new = CTRL_IDLE;
|
||||
touch_sense_ctrl_we = 1'h0;
|
||||
|
||||
case (touch_sense_ctrl_reg)
|
||||
CTRL_IDLE : begin
|
||||
if (touch_event_sample1_reg) begin
|
||||
touch_event_set = 1'h1;
|
||||
touch_sense_ctrl_new = CTRL_EVENT;
|
||||
touch_sense_ctrl_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
CTRL_EVENT: begin
|
||||
if (api_clear_event) begin
|
||||
touch_event_rst = 1'h1;
|
||||
touch_sense_ctrl_new = CTRL_WAIT;
|
||||
touch_sense_ctrl_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
CTRL_WAIT: begin
|
||||
if (!touch_event_sample1_reg) begin
|
||||
touch_sense_ctrl_new = CTRL_IDLE;
|
||||
touch_sense_ctrl_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
default : begin
|
||||
end
|
||||
endcase // case (touch_sense_ctrl_reg)
|
||||
end
|
||||
|
||||
endmodule // touch_sense
|
||||
|
||||
//======================================================================
|
||||
// EOF touch_sense.v
|
||||
//======================================================================
|
276
hw/application_fpga/core/touch_sense/tb/tb_touch_sense.v
Normal file
276
hw/application_fpga/core/touch_sense/tb/tb_touch_sense.v
Normal file
|
@ -0,0 +1,276 @@
|
|||
//======================================================================
|
||||
//
|
||||
// tb_touch_sense.v
|
||||
// ----------------
|
||||
// Testbench for the touch sense core.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module tb_touch_sense();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
parameter DEBUG = 0;
|
||||
parameter DUMP_WAIT = 0;
|
||||
|
||||
parameter CLK_HALF_PERIOD = 1;
|
||||
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
|
||||
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_STATUS = 8'h09;
|
||||
localparam STATUS_READY_BIT = 0;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Register and Wire declarations.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] cycle_ctr;
|
||||
reg [31 : 0] error_ctr;
|
||||
reg [31 : 0] tc_ctr;
|
||||
reg tb_monitor;
|
||||
|
||||
reg tb_clk;
|
||||
reg tb_reset_n;
|
||||
reg tb_touch_event;
|
||||
reg tb_cs;
|
||||
reg tb_we;
|
||||
reg [7 : 0] tb_address;
|
||||
wire [31 : 0] tb_read_data;
|
||||
|
||||
reg [31 : 0] read_data;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Device Under Test.
|
||||
//----------------------------------------------------------------
|
||||
touch_sense dut(
|
||||
.clk(tb_clk),
|
||||
.reset_n(tb_reset_n),
|
||||
|
||||
.touch_event(tb_touch_event),
|
||||
|
||||
.cs(tb_cs),
|
||||
.we(tb_we),
|
||||
.address(tb_address),
|
||||
.read_data(tb_read_data)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// clk_gen
|
||||
//
|
||||
// Always running clock generator process.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : clk_gen
|
||||
#CLK_HALF_PERIOD;
|
||||
tb_clk = !tb_clk;
|
||||
end // clk_gen
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// sys_monitor()
|
||||
//
|
||||
// An always running process that creates a cycle counter and
|
||||
// conditionally displays information about the DUT.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : sys_monitor
|
||||
cycle_ctr = cycle_ctr + 1;
|
||||
#(CLK_PERIOD);
|
||||
if (tb_monitor)
|
||||
begin
|
||||
dump_dut_state();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// dump_dut_state()
|
||||
//
|
||||
// Dump the state of the dump when needed.
|
||||
//----------------------------------------------------------------
|
||||
task dump_dut_state;
|
||||
begin
|
||||
$display("State of DUT");
|
||||
$display("------------");
|
||||
$display("Cycle: %08d", cycle_ctr);
|
||||
$display("");
|
||||
end
|
||||
endtask // dump_dut_state
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reset_dut()
|
||||
//
|
||||
// Toggle reset to put the DUT into a well known state.
|
||||
//----------------------------------------------------------------
|
||||
task reset_dut;
|
||||
begin
|
||||
$display("--- Toggle reset.");
|
||||
tb_reset_n = 0;
|
||||
#(2 * CLK_PERIOD);
|
||||
tb_reset_n = 1;
|
||||
end
|
||||
endtask // reset_dut
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// display_test_result()
|
||||
//
|
||||
// Display the accumulated test results.
|
||||
//----------------------------------------------------------------
|
||||
task display_test_result;
|
||||
begin
|
||||
if (error_ctr == 0)
|
||||
begin
|
||||
$display("--- All %02d test cases completed successfully", tc_ctr);
|
||||
end
|
||||
else
|
||||
begin
|
||||
$display("--- %02d tests completed - %02d test cases did not complete successfully.",
|
||||
tc_ctr, error_ctr);
|
||||
end
|
||||
end
|
||||
endtask // display_test_result
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// init_sim()
|
||||
//
|
||||
// Initialize all counters and testbed functionality as well
|
||||
// as setting the DUT inputs to defined values.
|
||||
//----------------------------------------------------------------
|
||||
task init_sim;
|
||||
begin
|
||||
cycle_ctr = 0;
|
||||
error_ctr = 0;
|
||||
tc_ctr = 0;
|
||||
tb_monitor = 0;
|
||||
|
||||
tb_clk = 1'h0;
|
||||
tb_reset_n = 1'h1;
|
||||
tb_touch_event = 1'h0;
|
||||
tb_cs = 1'h0;
|
||||
tb_we = 1'h0;
|
||||
tb_address = 8'h0;
|
||||
end
|
||||
endtask // init_sim
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// write_word()
|
||||
//
|
||||
// Write the given word to the DUT using the DUT interface.
|
||||
//----------------------------------------------------------------
|
||||
task write_word(input [11 : 0] address,
|
||||
input [31 : 0] word);
|
||||
begin
|
||||
if (DEBUG)
|
||||
begin
|
||||
$display("--- Writing 0x%08x to 0x%02x.", word, address);
|
||||
$display("");
|
||||
end
|
||||
|
||||
tb_address = address;
|
||||
tb_cs = 1;
|
||||
tb_we = 1;
|
||||
#(2 * CLK_PERIOD);
|
||||
tb_cs = 0;
|
||||
tb_we = 0;
|
||||
end
|
||||
endtask // write_word
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// read_word()
|
||||
//
|
||||
// Read a data word from the given address in the DUT.
|
||||
// the word read will be available in the global variable
|
||||
// read_data.
|
||||
//----------------------------------------------------------------
|
||||
task read_word(input [11 : 0] address);
|
||||
begin
|
||||
tb_address = address;
|
||||
tb_cs = 1;
|
||||
tb_we = 0;
|
||||
#(CLK_PERIOD);
|
||||
read_data = tb_read_data;
|
||||
tb_cs = 0;
|
||||
|
||||
if (DEBUG)
|
||||
begin
|
||||
$display("--- Reading 0x%08x from 0x%02x.", read_data, address);
|
||||
$display("");
|
||||
end
|
||||
end
|
||||
endtask // read_word
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// wait_ready()
|
||||
//
|
||||
// Wait for the ready flag to be set in dut.
|
||||
//----------------------------------------------------------------
|
||||
task wait_ready;
|
||||
begin : wready
|
||||
read_word(ADDR_STATUS);
|
||||
while (read_data == 0)
|
||||
read_word(ADDR_STATUS);
|
||||
end
|
||||
endtask // wait_ready
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// test1()
|
||||
//----------------------------------------------------------------
|
||||
task test1;
|
||||
begin
|
||||
tc_ctr = tc_ctr + 1;
|
||||
|
||||
$display("");
|
||||
$display("--- test1: started.");
|
||||
|
||||
$display("--- test1: completed.");
|
||||
$display("");
|
||||
end
|
||||
endtask // tes1
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// touch_sense_test
|
||||
//----------------------------------------------------------------
|
||||
initial
|
||||
begin : timer_test
|
||||
$display("");
|
||||
$display(" -= Testbench for touch_sense started =-");
|
||||
$display(" ====================================");
|
||||
$display("");
|
||||
|
||||
init_sim();
|
||||
reset_dut();
|
||||
test1();
|
||||
|
||||
display_test_result();
|
||||
$display("");
|
||||
$display(" -= Testbench for touch_sense completed =-");
|
||||
$display(" ======================================");
|
||||
$display("");
|
||||
$finish;
|
||||
end // touch_sense_test
|
||||
endmodule // tb_touch_sense
|
||||
|
||||
//======================================================================
|
||||
// EOF tb_touch_sense.v
|
||||
//======================================================================
|
56
hw/application_fpga/core/touch_sense/toolruns/Makefile
Executable file
56
hw/application_fpga/core/touch_sense/toolruns/Makefile
Executable file
|
@ -0,0 +1,56 @@
|
|||
#===================================================================
|
||||
#
|
||||
# Makefile
|
||||
# --------
|
||||
# Makefile for building the touch sense top simulations.
|
||||
#
|
||||
#
|
||||
# Author: Joachim Strombergson
|
||||
# Copyright (C) 2022 - Tillitis AB
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
#===================================================================
|
||||
|
||||
TOP_SRC=../rtl/touch_sense.v
|
||||
TB_TOP_SRC =../tb/tb_touch_sense.v
|
||||
|
||||
CC = iverilog
|
||||
CC_FLAGS = -Wall
|
||||
|
||||
LINT = verilator
|
||||
LINT_FLAGS = +1364-2001ext+ --lint-only -Wall -Wno-fatal -Wno-DECLFILENAME
|
||||
|
||||
|
||||
all: top.sim
|
||||
|
||||
|
||||
top.sim: $(TB_TOP_SRC) $(TOP_SRC)
|
||||
$(CC) $(CC_FLAGS) -o top.sim $(TB_TOP_SRC) $(TOP_SRC)
|
||||
|
||||
|
||||
sim-top: top.sim
|
||||
./top.sim
|
||||
|
||||
|
||||
lint-top: $(TOP_SRC)
|
||||
$(LINT) $(LINT_FLAGS) $(TOP_SRC)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f top.sim
|
||||
|
||||
|
||||
help:
|
||||
@echo "Build system for simulation of touch sense core"
|
||||
@echo ""
|
||||
@echo "Supported targets:"
|
||||
@echo "------------------"
|
||||
@echo "all: Build all simulation targets."
|
||||
@echo "top.sim: Build top level simulation target."
|
||||
@echo "sim-top: Run top level simulation."
|
||||
@echo "lint-top: Lint top rtl source files."
|
||||
@echo "clean: Delete all built files."
|
||||
|
||||
#===================================================================
|
||||
# EOF Makefile
|
||||
#===================================================================
|
29
hw/application_fpga/core/trng/README.md
Normal file
29
hw/application_fpga/core/trng/README.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# trng
|
||||
Implementation of the FiGaRO TRNG for FPGAs
|
||||
|
||||
## Introduction
|
||||
# figaro
|
||||
|
||||
|
||||
## Status
|
||||
First version completed. In testing. Use with caution.
|
||||
|
||||
|
||||
## Introduction
|
||||
This is a an implementation of the FiGaRO true random
|
||||
number generator (TRNG) [1]. The main FPGA target is Lattice iCE40
|
||||
UltraPlus, but adaption to other FPGAs should be easy to do.
|
||||
|
||||
|
||||
## Implementation details
|
||||
The implementation instantiates four FiRO and four GaRO modules. The
|
||||
modules includes state sampling. The polynomials used for the
|
||||
oscillators are given by equotions (9)..(16) in paper [1]. The eight
|
||||
outputs are then XORed together to form a one bit random value.
|
||||
|
||||
The random bit value is sampled at a rate controlled by a 24 bit
|
||||
divisor.
|
||||
|
||||
## References
|
||||
[1] [True Random Number Generator Based on Fibonacci-Galois
|
||||
Ring Oscillators for FPGA](https://www.mdpi.com/2076-3417/11/8/3330/pdf)
|
129
hw/application_fpga/core/trng/rtl/figaro.v
Normal file
129
hw/application_fpga/core/trng/rtl/figaro.v
Normal file
|
@ -0,0 +1,129 @@
|
|||
//======================================================================
|
||||
//
|
||||
// figaro.v
|
||||
// --------
|
||||
// Top level wrapper for the figaro core.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module figaro(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire cs,
|
||||
input wire we,
|
||||
input wire [7 : 0] address,
|
||||
input wire [31 : 0] write_data,
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_STATUS = 8'h09;
|
||||
localparam STATUS_READY_BIT = 0;
|
||||
|
||||
localparam ADDR_SAMPLE_RATE = 8'h10;
|
||||
|
||||
localparam ADDR_ENTROPY = 8'h20;
|
||||
|
||||
localparam CORE_NAME0 = 32'h66696761; // "figa"
|
||||
localparam CORE_NAME1 = 32'h726f2020; // "ro "
|
||||
localparam CORE_VERSION = 32'h00000001;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
reg core_read_entropy;
|
||||
reg core_set_sample_rate;
|
||||
wire [31 : 0] core_entropy;
|
||||
wire core_ready;
|
||||
reg [31 : 0] tmp_read_data;
|
||||
reg tmp_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = tmp_read_data;
|
||||
assign ready = tmp_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// core instantiation.
|
||||
//----------------------------------------------------------------
|
||||
figaro_core core(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.read_entropy(core_read_entropy),
|
||||
.set_sample_rate(core_set_sample_rate),
|
||||
.sample_rate(write_data[23 : 0]),
|
||||
.entropy(core_entropy),
|
||||
.ready(core_ready)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// api
|
||||
//
|
||||
// The interface command decoding logic.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : api
|
||||
core_read_entropy = 1'h0;
|
||||
core_set_sample_rate = 1'h0;
|
||||
tmp_read_data = 32'h0;
|
||||
tmp_ready = 1'h0;
|
||||
|
||||
if (cs) begin
|
||||
tmp_ready = 1'h1;
|
||||
|
||||
if (we) begin
|
||||
if (address == ADDR_SAMPLE_RATE) begin
|
||||
core_set_sample_rate = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
else begin
|
||||
if (address == ADDR_NAME0) begin
|
||||
tmp_read_data = CORE_NAME0;
|
||||
end
|
||||
|
||||
if (address == ADDR_NAME1) begin
|
||||
tmp_read_data = CORE_NAME1;
|
||||
end
|
||||
|
||||
if (address == ADDR_VERSION) begin
|
||||
tmp_read_data = CORE_VERSION;
|
||||
end
|
||||
|
||||
if (address == ADDR_STATUS) begin
|
||||
tmp_read_data = {31'h0, core_ready};
|
||||
end
|
||||
|
||||
if (address == ADDR_ENTROPY) begin
|
||||
tmp_read_data = core_entropy;
|
||||
core_read_entropy = 1'h1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // api
|
||||
endmodule // figaro
|
||||
|
||||
//======================================================================
|
||||
// EOF figaro.v
|
||||
//======================================================================
|
204
hw/application_fpga/core/trng/rtl/figaro_core.v
Normal file
204
hw/application_fpga/core/trng/rtl/figaro_core.v
Normal file
|
@ -0,0 +1,204 @@
|
|||
//======================================================================
|
||||
//
|
||||
// figaro_core.v
|
||||
// -----------
|
||||
// FiGaRO based FIGARO for iCE40 device.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module figaro_core(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire set_sample_rate,
|
||||
input wire [23 : 0] sample_rate,
|
||||
|
||||
input wire read_entropy,
|
||||
output wire [31 : 0] entropy,
|
||||
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Local parameters.
|
||||
//---------------------------------------------------------------
|
||||
localparam DEFAULT_SAMPLE_RATE = 24'h010000;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Registers.
|
||||
//---------------------------------------------------------------
|
||||
reg [23 : 0] sample_rate_ctr_reg;
|
||||
reg [23 : 0] sample_rate_ctr_new;
|
||||
|
||||
reg [23 : 0] sample_rate_reg;
|
||||
reg sample_rate_we;
|
||||
|
||||
reg [5 : 0] bit_ctr_reg;
|
||||
reg [5 : 0] bit_ctr_new;
|
||||
reg bit_ctr_rst;
|
||||
reg bit_ctr_inc;
|
||||
reg bit_ctr_we;
|
||||
|
||||
reg [31 : 0] entropy_reg;
|
||||
reg [31 : 0] entropy_new;
|
||||
reg entropy_we;
|
||||
|
||||
reg ready_reg;
|
||||
reg ready_new;
|
||||
reg ready_we;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Firo oscillator instances and XOR combined result.
|
||||
//---------------------------------------------------------------
|
||||
wire firo_ent[3 : 0];
|
||||
wire firo_entropy;
|
||||
|
||||
firo #(.POLY(10'b1111110111)) firo0(.clk(clk), .entropy(firo_ent[0]));
|
||||
firo #(.POLY(10'b1011111001)) firo1(.clk(clk), .entropy(firo_ent[1]));
|
||||
firo #(.POLY(10'b1100000001)) firo2(.clk(clk), .entropy(firo_ent[2]));
|
||||
firo #(.POLY(10'b1011111111)) firo3(.clk(clk), .entropy(firo_ent[3]));
|
||||
|
||||
assign firo_entropy = firo_ent[0] ^ firo_ent[1] ^
|
||||
firo_ent[2] ^ firo_ent[3];
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// garo oscillator instances and XOR combined result.
|
||||
//---------------------------------------------------------------
|
||||
wire garo_ent[3 : 0];
|
||||
wire garo_entropy;
|
||||
|
||||
garo #(.POLY(11'b11111101111)) garo0(.clk(clk), .entropy(garo_ent[0]));
|
||||
garo #(.POLY(11'b10111110011)) garo1(.clk(clk), .entropy(garo_ent[1]));
|
||||
garo #(.POLY(11'b11000000011)) garo2(.clk(clk), .entropy(garo_ent[2]));
|
||||
garo #(.POLY(11'b10111111111)) garo3(.clk(clk), .entropy(garo_ent[3]));
|
||||
|
||||
assign garo_entropy = garo_ent[0] ^ garo_ent[1] ^
|
||||
garo_ent[2] ^ garo_ent[3];
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Assignments.
|
||||
//---------------------------------------------------------------
|
||||
assign ready = ready_reg;
|
||||
assign entropy = entropy_reg;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// reg_update
|
||||
//---------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
if (!reset_n) begin
|
||||
sample_rate_reg <= DEFAULT_SAMPLE_RATE;
|
||||
sample_rate_ctr_reg <= 24'h0;
|
||||
bit_ctr_reg <= 6'h0;
|
||||
entropy_reg <= 32'h0;
|
||||
ready_reg <= 1'h0;
|
||||
end
|
||||
else begin
|
||||
sample_rate_ctr_reg <= sample_rate_ctr_new;
|
||||
|
||||
if (sample_rate_we) begin
|
||||
sample_rate_reg <= sample_rate;
|
||||
end
|
||||
|
||||
if (bit_ctr_we) begin
|
||||
bit_ctr_reg <= bit_ctr_new;
|
||||
end
|
||||
|
||||
if (entropy_we) begin
|
||||
entropy_reg <= entropy_new;
|
||||
end
|
||||
|
||||
if (ready_we) begin
|
||||
ready_reg <= ready_new;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// ready_logic
|
||||
//
|
||||
// After an entropy word has been read we wait 32 bits before
|
||||
// setting ready again, indicating that a new word is ready.
|
||||
//---------------------------------------------------------------
|
||||
always @*
|
||||
begin : ready_logic;
|
||||
bit_ctr_new = 6'h0;
|
||||
bit_ctr_we = 1'h0;
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h0;
|
||||
|
||||
if (bit_ctr_reg >= 6'h20) begin
|
||||
ready_new = 1'h1;
|
||||
ready_we = 1'h1;
|
||||
end
|
||||
|
||||
if (bit_ctr_rst) begin
|
||||
bit_ctr_new = 6'h0;
|
||||
bit_ctr_we = 1'h1;
|
||||
ready_new = 1'h0;
|
||||
ready_we = 1'h1;
|
||||
end
|
||||
|
||||
else if (bit_ctr_inc) begin
|
||||
if (bit_ctr_reg < 6'h24) begin
|
||||
bit_ctr_new = bit_ctr_reg + 1'h1;
|
||||
bit_ctr_we = 1'h1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// figaro_sample_logic
|
||||
//
|
||||
// Wait sample_rate_reg number of cycles between sampling a bit
|
||||
// from the entropy source.
|
||||
//---------------------------------------------------------------
|
||||
always @*
|
||||
begin : figaro_sample_logic
|
||||
sample_rate_we = 1'h0;
|
||||
bit_ctr_rst = 1'h0;
|
||||
bit_ctr_inc = 1'h0;
|
||||
entropy_we = 1'h0;
|
||||
|
||||
entropy_new = {entropy_reg[30 : 0], firo_entropy ^ garo_entropy};
|
||||
|
||||
if (read_entropy) begin
|
||||
bit_ctr_rst = 1'h1;
|
||||
sample_rate_ctr_new = 24'h0;
|
||||
end
|
||||
|
||||
else if (set_sample_rate) begin
|
||||
bit_ctr_rst = 1'h1;
|
||||
sample_rate_we = 1'h1;
|
||||
sample_rate_ctr_new = 24'h0;
|
||||
end
|
||||
|
||||
else if (sample_rate_ctr_reg == sample_rate_reg) begin
|
||||
sample_rate_ctr_new = 24'h0;
|
||||
entropy_we = 1'h1;
|
||||
bit_ctr_inc = 1'h1;
|
||||
end
|
||||
|
||||
else begin
|
||||
sample_rate_ctr_new = sample_rate_ctr_reg + 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // figaro_core
|
||||
|
||||
//======================================================================
|
||||
// EOF figaro_core.v
|
||||
//======================================================================
|
75
hw/application_fpga/core/trng/rtl/firo.v
Normal file
75
hw/application_fpga/core/trng/rtl/firo.v
Normal file
|
@ -0,0 +1,75 @@
|
|||
//======================================================================
|
||||
//
|
||||
// firo.v
|
||||
// ------
|
||||
// Fibonacci Ring Oscillator with state sampling.
|
||||
// The Fibonacci depth is 10 bits, and the bits are always sampled.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module firo(
|
||||
input wire clk,
|
||||
output wire entropy
|
||||
);
|
||||
|
||||
parameter POLY = 10'b1111111111;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers and wires.
|
||||
//----------------------------------------------------------------
|
||||
reg entropy_reg;
|
||||
wire [10 : 0] f;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Combinational loop inverters.
|
||||
//---------------------------------------------------------------
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv1 (.I0(f[0]), .O(f[1]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv2 (.I0(f[1]), .O(f[2]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv3 (.I0(f[2]), .O(f[3]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv4 (.I0(f[3]), .O(f[4]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv5 (.I0(f[4]), .O(f[5]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv6 (.I0(f[5]), .O(f[6]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv7 (.I0(f[6]), .O(f[7]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv8 (.I0(f[7]), .O(f[8]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv9 (.I0(f[8]), .O(f[9]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv10 (.I0(f[9]), .O(f[10]));
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// parameterized feedback logic.
|
||||
//---------------------------------------------------------------
|
||||
assign f[0] = (POLY[0] & f[1]) ^ (POLY[1] & f[2]) ^
|
||||
(POLY[2] & f[3]) ^ (POLY[3] & f[4]) ^
|
||||
(POLY[4] & f[5]) ^ (POLY[5] & f[6]) ^
|
||||
(POLY[6] & f[7]) ^ (POLY[7] & f[8]) ^
|
||||
(POLY[8] & f[9]) ^ (POLY[9] & f[10]);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign entropy = entropy_reg;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// reg_update
|
||||
//---------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
entropy_reg <= ^f;
|
||||
end
|
||||
|
||||
endmodule // firo
|
||||
|
||||
//======================================================================
|
||||
// EOF firo.v
|
||||
//======================================================================
|
85
hw/application_fpga/core/trng/rtl/garo.v
Normal file
85
hw/application_fpga/core/trng/rtl/garo.v
Normal file
|
@ -0,0 +1,85 @@
|
|||
//======================================================================
|
||||
//
|
||||
// garo.v
|
||||
// ------
|
||||
// GaloisRing Oscillator with state sampling.
|
||||
// The Galois depth is 11 bits, and the bits are always sampled.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module garo(
|
||||
input wire clk,
|
||||
output wire entropy
|
||||
);
|
||||
|
||||
parameter POLY = 11'b11111111111;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers and wires.
|
||||
//----------------------------------------------------------------
|
||||
reg entropy_reg;
|
||||
wire [11 : 0] g;
|
||||
wire [11 : 0] gp;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Combinational loop inverters.
|
||||
//---------------------------------------------------------------
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv1 (.I0(g[0]), .O(gp[0]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv2 (.I0(g[1]), .O(gp[1]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv3 (.I0(g[2]), .O(gp[2]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv4 (.I0(g[3]), .O(gp[3]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv5 (.I0(g[4]), .O(gp[4]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv6 (.I0(g[5]), .O(gp[5]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv7 (.I0(g[6]), .O(gp[6]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv8 (.I0(g[7]), .O(gp[7]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv9 (.I0(g[8]), .O(gp[8]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv10 (.I0(g[9]), .O(gp[9]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv11 (.I0(g[10]), .O(gp[10]));
|
||||
(* keep *) SB_LUT4 #(.LUT_INIT(1'b1)) osc_inv12 (.I0(g[11]), .O(gp[11]));
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// parameterized feedback logic.
|
||||
//---------------------------------------------------------------
|
||||
assign g[11] = gp[0];
|
||||
assign g[10] = gp[11] ^ (POLY[10] & gp[0]);
|
||||
assign g[9] = gp[10] ^ (POLY[9] & gp[0]);
|
||||
assign g[8] = gp[9] ^ (POLY[8] & gp[0]);
|
||||
assign g[7] = gp[8] ^ (POLY[7] & gp[0]);
|
||||
assign g[6] = gp[7] ^ (POLY[6] & gp[0]);
|
||||
assign g[5] = gp[6] ^ (POLY[5] & gp[0]);
|
||||
assign g[4] = gp[5] ^ (POLY[4] & gp[0]);
|
||||
assign g[3] = gp[4] ^ (POLY[3] & gp[0]);
|
||||
assign g[2] = gp[3] ^ (POLY[2] & gp[0]);
|
||||
assign g[1] = gp[2] ^ (POLY[1] & gp[0]);
|
||||
assign g[0] = gp[1] ^ (POLY[0] & gp[0]);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign entropy = entropy_reg;
|
||||
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// reg_update
|
||||
//---------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
entropy_reg <= ^g;
|
||||
end
|
||||
|
||||
endmodule // garo
|
||||
|
||||
//======================================================================
|
||||
// EOF garo.v
|
||||
//======================================================================
|
23
hw/application_fpga/core/uart/LICENSE
Normal file
23
hw/application_fpga/core/uart/LICENSE
Normal file
|
@ -0,0 +1,23 @@
|
|||
Copyright (c) 2014, Joachim Strömbergson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
9
hw/application_fpga/core/uart/README.md
Normal file
9
hw/application_fpga/core/uart/README.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
uart
|
||||
====
|
||||
|
||||
A simple universal asynchronous receiver/transmitter (UART) core
|
||||
implemented in Verilog.
|
||||
|
||||
|
||||
# Status
|
||||
The core is completed and has been used in several FPGA designs.
|
306
hw/application_fpga/core/uart/rtl/uart.v
Normal file
306
hw/application_fpga/core/uart/rtl/uart.v
Normal file
|
@ -0,0 +1,306 @@
|
|||
//======================================================================
|
||||
//
|
||||
// uart.v
|
||||
// ------
|
||||
// Top level wrapper for the uart core.
|
||||
//
|
||||
// A simple universal asynchronous receiver/transmitter (UART)
|
||||
// interface. The interface contains 16 byte wide transmit and
|
||||
// receivea buffers and can handle start and stop bits. But in
|
||||
// general is rather simple. The primary purpose is as host
|
||||
// interface for the coretest design. The core also has a
|
||||
// loopback mode to allow testing of a serial link.
|
||||
//
|
||||
// Note that the UART has a separate API interface to allow
|
||||
// a control core to change settings such as speed. But the core
|
||||
// has default values to allow it to start operating directly
|
||||
// after reset. No config should be needed.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (c) 2014, Secworks Sweden AB
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or
|
||||
// without modification, are permitted provided that the following
|
||||
// conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module uart(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire rxd,
|
||||
output wire txd,
|
||||
|
||||
input wire cs,
|
||||
input wire we,
|
||||
input wire [7 : 0] address,
|
||||
input wire [31 : 0] write_data,
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam ADDR_CORE_NAME0 = 8'h00;
|
||||
localparam ADDR_CORE_NAME1 = 8'h01;
|
||||
localparam ADDR_CORE_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_BIT_RATE = 8'h10;
|
||||
localparam ADDR_DATA_BITS = 8'h11;
|
||||
localparam ADDR_STOP_BITS = 8'h12;
|
||||
|
||||
localparam ADDR_RX_STATUS = 8'h20;
|
||||
localparam ADDR_RX_DATA = 8'h21;
|
||||
|
||||
localparam ADDR_TX_STATUS = 8'h40;
|
||||
localparam ADDR_TX_DATA = 8'h41;
|
||||
|
||||
|
||||
localparam CORE_NAME0 = 32'h75617274; // "uart"
|
||||
localparam CORE_NAME1 = 32'h20202020; // " "
|
||||
localparam CORE_VERSION = 32'h00000004;
|
||||
|
||||
|
||||
// The default bit rate is based on target clock frequency
|
||||
// divided by the bit rate times in order to hit the
|
||||
// center of the bits. I.e.
|
||||
// Clock: 12 MHz, 38400 bps
|
||||
// Divisor = 12*10E6 / 38400 = 312
|
||||
localparam DEFAULT_BIT_RATE = 16'd312;
|
||||
localparam DEFAULT_DATA_BITS = 4'h8;
|
||||
localparam DEFAULT_STOP_BITS = 2'h1;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg [15 : 0] bit_rate_reg;
|
||||
reg bit_rate_we;
|
||||
|
||||
reg [3 : 0] data_bits_reg;
|
||||
reg data_bits_we;
|
||||
|
||||
reg [1 : 0] stop_bits_reg;
|
||||
reg stop_bits_we;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
wire core_rxd_syn;
|
||||
wire [7 : 0] core_rxd_data;
|
||||
wire core_rxd_ack;
|
||||
|
||||
reg core_txd_syn;
|
||||
reg [7 : 0] core_txd_data;
|
||||
wire core_txd_ready;
|
||||
|
||||
wire fifo_out_syn;
|
||||
wire [7 : 0] fifo_out_data;
|
||||
reg fifo_out_ack;
|
||||
|
||||
reg [31 : 0] tmp_read_data;
|
||||
reg tmp_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = tmp_read_data;
|
||||
assign ready = tmp_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Module instantiations.
|
||||
//----------------------------------------------------------------
|
||||
uart_core core(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
// Configuration parameters
|
||||
.bit_rate(bit_rate_reg),
|
||||
.data_bits(data_bits_reg),
|
||||
.stop_bits(stop_bits_reg),
|
||||
|
||||
// External data interface
|
||||
.rxd(rxd),
|
||||
.txd(txd),
|
||||
|
||||
// Internal receive interface.
|
||||
.rxd_syn(core_rxd_syn),
|
||||
.rxd_data(core_rxd_data),
|
||||
.rxd_ack(core_rxd_ack),
|
||||
|
||||
// Internal transmit interface.
|
||||
.txd_syn(core_txd_syn),
|
||||
.txd_data(core_txd_data),
|
||||
.txd_ready(core_txd_ready)
|
||||
);
|
||||
|
||||
|
||||
uart_fifo fifo(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.in_syn(core_rxd_syn),
|
||||
.in_data(core_rxd_data),
|
||||
.in_ack(core_rxd_ack),
|
||||
|
||||
.out_syn(fifo_out_syn),
|
||||
.out_data(fifo_out_data),
|
||||
.out_ack(fifo_out_ack)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//
|
||||
// Update functionality for all registers in the core.
|
||||
// All registers are positive edge triggered with synchronous
|
||||
// active low reset.
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin: reg_update
|
||||
if (!reset_n) begin
|
||||
bit_rate_reg <= DEFAULT_BIT_RATE;
|
||||
data_bits_reg <= DEFAULT_DATA_BITS;
|
||||
stop_bits_reg <= DEFAULT_STOP_BITS;
|
||||
end
|
||||
else begin
|
||||
if (bit_rate_we) begin
|
||||
bit_rate_reg <= write_data[15 : 0];
|
||||
end
|
||||
|
||||
if (data_bits_we) begin
|
||||
data_bits_reg <= write_data[3 : 0];
|
||||
end
|
||||
|
||||
if (stop_bits_we) begin
|
||||
stop_bits_reg <= write_data[1 : 0];
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// api
|
||||
//
|
||||
// The core API that allows an internal host to control the
|
||||
// core functionality.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin: api
|
||||
// Default assignments.
|
||||
bit_rate_we = 1'h0;
|
||||
data_bits_we = 1'h0;
|
||||
stop_bits_we = 1'h0;
|
||||
core_txd_syn = 1'h0;
|
||||
fifo_out_ack = 1'h0;
|
||||
tmp_read_data = 32'h0;
|
||||
tmp_ready = 1'h0;
|
||||
|
||||
core_txd_data = write_data[7 : 0];
|
||||
|
||||
if (cs) begin
|
||||
tmp_ready = 1'h1;
|
||||
|
||||
if (we) begin
|
||||
case (address)
|
||||
ADDR_BIT_RATE: begin
|
||||
bit_rate_we = 1;
|
||||
end
|
||||
|
||||
ADDR_DATA_BITS: begin
|
||||
data_bits_we = 1;
|
||||
end
|
||||
|
||||
ADDR_STOP_BITS: begin
|
||||
stop_bits_we = 1;
|
||||
end
|
||||
|
||||
ADDR_TX_DATA: begin
|
||||
core_txd_syn = 1'h1;
|
||||
end
|
||||
|
||||
default: begin
|
||||
end
|
||||
endcase // case (address)
|
||||
end
|
||||
|
||||
else begin
|
||||
case (address)
|
||||
ADDR_CORE_NAME0: begin
|
||||
tmp_read_data = CORE_NAME0;
|
||||
end
|
||||
|
||||
ADDR_CORE_NAME1: begin
|
||||
tmp_read_data = CORE_NAME1;
|
||||
end
|
||||
|
||||
ADDR_CORE_VERSION: begin
|
||||
tmp_read_data = CORE_VERSION;
|
||||
end
|
||||
|
||||
ADDR_BIT_RATE: begin
|
||||
tmp_read_data = {16'h0, bit_rate_reg};
|
||||
end
|
||||
|
||||
ADDR_DATA_BITS: begin
|
||||
tmp_read_data = {28'h0, data_bits_reg};
|
||||
end
|
||||
|
||||
ADDR_STOP_BITS: begin
|
||||
tmp_read_data = {30'h0, stop_bits_reg};
|
||||
end
|
||||
|
||||
ADDR_RX_STATUS: begin
|
||||
tmp_read_data = {31'h0, fifo_out_syn};
|
||||
end
|
||||
|
||||
ADDR_RX_DATA: begin
|
||||
fifo_out_ack = 1'h1;
|
||||
tmp_read_data = {24'h0, fifo_out_data};
|
||||
end
|
||||
|
||||
ADDR_TX_STATUS: begin
|
||||
tmp_read_data = {31'h0, core_txd_ready};
|
||||
end
|
||||
|
||||
default: begin
|
||||
end
|
||||
endcase // case (address)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // uart
|
||||
|
||||
//======================================================================
|
||||
// EOF uart.v
|
||||
//======================================================================
|
532
hw/application_fpga/core/uart/rtl/uart_core.v
Normal file
532
hw/application_fpga/core/uart/rtl/uart_core.v
Normal file
|
@ -0,0 +1,532 @@
|
|||
//======================================================================
|
||||
//
|
||||
// uart_core.v
|
||||
// -----------
|
||||
// A simple universal asynchronous receiver/transmitter (UART)
|
||||
// interface. The interface contains 16 byte wide transmit and
|
||||
// receivea buffers and can handle start and stop bits. But in
|
||||
// general is rather simple. The primary purpose is as host
|
||||
// interface for the coretest design. The core also has a
|
||||
// loopback mode to allow testing of a serial link.
|
||||
//
|
||||
// Note that the UART has a separate API interface to allow
|
||||
// a control core to change settings such as speed. But the core
|
||||
// has default values to allow it to start operating directly
|
||||
// after reset. No config should be needed.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (c) 2014, Secworks Sweden AB
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
// Redistribution and use in source and binary forms, with or
|
||||
// without modification, are permitted provided that the following
|
||||
// conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module uart_core(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
// Configuration parameters
|
||||
input wire [15 : 0] bit_rate,
|
||||
input wire [3 : 0] data_bits,
|
||||
input wire [1 : 0] stop_bits,
|
||||
|
||||
// External data interface
|
||||
input wire rxd,
|
||||
output wire txd,
|
||||
|
||||
// Internal receive interface.
|
||||
output wire rxd_syn,
|
||||
output [7 : 0] rxd_data,
|
||||
input wire rxd_ack,
|
||||
|
||||
// Internal transmit interface.
|
||||
input wire txd_syn,
|
||||
input wire [7 : 0] txd_data,
|
||||
output wire txd_ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
parameter ERX_IDLE = 0;
|
||||
parameter ERX_START = 1;
|
||||
parameter ERX_BITS = 2;
|
||||
parameter ERX_STOP = 3;
|
||||
parameter ERX_SYN = 4;
|
||||
|
||||
parameter ETX_IDLE = 0;
|
||||
parameter ETX_ACK = 1;
|
||||
parameter ETX_START = 2;
|
||||
parameter ETX_BITS = 3;
|
||||
parameter ETX_STOP = 4;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg rxd0_reg;
|
||||
reg rxd_reg;
|
||||
|
||||
reg [7 : 0] rxd_byte_reg;
|
||||
reg rxd_byte_we;
|
||||
|
||||
reg [4 : 0] rxd_bit_ctr_reg;
|
||||
reg [4 : 0] rxd_bit_ctr_new;
|
||||
reg rxd_bit_ctr_we;
|
||||
reg rxd_bit_ctr_rst;
|
||||
reg rxd_bit_ctr_inc;
|
||||
|
||||
reg [15 : 0] rxd_bitrate_ctr_reg;
|
||||
reg [15 : 0] rxd_bitrate_ctr_new;
|
||||
reg rxd_bitrate_ctr_we;
|
||||
reg rxd_bitrate_ctr_rst;
|
||||
reg rxd_bitrate_ctr_inc;
|
||||
|
||||
reg rxd_syn_reg;
|
||||
reg rxd_syn_new;
|
||||
reg rxd_syn_we;
|
||||
|
||||
reg [2 : 0] erx_ctrl_reg;
|
||||
reg [2 : 0] erx_ctrl_new;
|
||||
reg erx_ctrl_we;
|
||||
|
||||
reg txd_reg;
|
||||
reg txd_new;
|
||||
reg txd_we;
|
||||
|
||||
reg [7 : 0] txd_byte_reg;
|
||||
reg [7 : 0] txd_byte_new;
|
||||
reg txd_byte_we;
|
||||
|
||||
reg [4 : 0] txd_bit_ctr_reg;
|
||||
reg [4 : 0] txd_bit_ctr_new;
|
||||
reg txd_bit_ctr_we;
|
||||
reg txd_bit_ctr_rst;
|
||||
reg txd_bit_ctr_inc;
|
||||
|
||||
reg [15 : 0] txd_bitrate_ctr_reg;
|
||||
reg [15 : 0] txd_bitrate_ctr_new;
|
||||
reg txd_bitrate_ctr_we;
|
||||
reg txd_bitrate_ctr_rst;
|
||||
reg txd_bitrate_ctr_inc;
|
||||
|
||||
reg txd_ready_reg;
|
||||
reg txd_ready_new;
|
||||
reg txd_ready_we;
|
||||
|
||||
reg [2 : 0] etx_ctrl_reg;
|
||||
reg [2 : 0] etx_ctrl_new;
|
||||
reg etx_ctrl_we;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
wire [15 : 0] half_bit_rate;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign txd = txd_reg;
|
||||
assign rxd_syn = rxd_syn_reg;
|
||||
assign rxd_data = rxd_byte_reg;
|
||||
assign txd_ready = txd_ready_reg;
|
||||
|
||||
assign half_bit_rate = {1'b0, bit_rate[15 : 1]};
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//
|
||||
// Update functionality for all registers in the core.
|
||||
// All registers are positive edge triggered with
|
||||
// synchronous active low reset.
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin: reg_update
|
||||
if (!reset_n) begin
|
||||
rxd0_reg <= 1'b0;
|
||||
rxd_reg <= 1'b0;
|
||||
rxd_byte_reg <= 8'h0;
|
||||
rxd_bit_ctr_reg <= 5'h0;
|
||||
rxd_bitrate_ctr_reg <= 16'h0;
|
||||
rxd_syn_reg <= 0;
|
||||
erx_ctrl_reg <= ERX_IDLE;
|
||||
|
||||
txd_reg <= 1'b1;
|
||||
txd_byte_reg <= 8'h0;
|
||||
txd_bit_ctr_reg <= 5'h0;
|
||||
txd_bitrate_ctr_reg <= 16'h0;
|
||||
txd_ready_reg <= 1'b1;
|
||||
etx_ctrl_reg <= ETX_IDLE;
|
||||
end
|
||||
|
||||
else begin
|
||||
rxd0_reg <= rxd;
|
||||
rxd_reg <= rxd0_reg;
|
||||
|
||||
if (rxd_byte_we) begin
|
||||
rxd_byte_reg <= {rxd_reg, rxd_byte_reg[7 : 1]};
|
||||
end
|
||||
|
||||
if (rxd_bit_ctr_we) begin
|
||||
rxd_bit_ctr_reg <= rxd_bit_ctr_new;
|
||||
end
|
||||
|
||||
if (rxd_bitrate_ctr_we) begin
|
||||
rxd_bitrate_ctr_reg <= rxd_bitrate_ctr_new;
|
||||
end
|
||||
|
||||
if (rxd_syn_we) begin
|
||||
rxd_syn_reg <= rxd_syn_new;
|
||||
end
|
||||
|
||||
if (erx_ctrl_we) begin
|
||||
erx_ctrl_reg <= erx_ctrl_new;
|
||||
end
|
||||
|
||||
if (txd_we) begin
|
||||
txd_reg <= txd_new;
|
||||
end
|
||||
|
||||
if (txd_byte_we) begin
|
||||
txd_byte_reg <= txd_byte_new;
|
||||
end
|
||||
|
||||
if (txd_bit_ctr_we) begin
|
||||
txd_bit_ctr_reg <= txd_bit_ctr_new;
|
||||
end
|
||||
|
||||
if (txd_bitrate_ctr_we) begin
|
||||
txd_bitrate_ctr_reg <= txd_bitrate_ctr_new;
|
||||
end
|
||||
|
||||
if (txd_ready_we) begin
|
||||
txd_ready_reg <= txd_ready_new;
|
||||
end
|
||||
|
||||
if (etx_ctrl_we) begin
|
||||
etx_ctrl_reg <= etx_ctrl_new;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// rxd_bit_ctr
|
||||
//
|
||||
// Bit counter for receiving data on the external
|
||||
// serial interface.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin: rxd_bit_ctr
|
||||
rxd_bit_ctr_new = 5'h0;
|
||||
rxd_bit_ctr_we = 1'b0;
|
||||
|
||||
if (rxd_bit_ctr_rst) begin
|
||||
rxd_bit_ctr_new = 5'h0;
|
||||
rxd_bit_ctr_we = 1'b1;
|
||||
end
|
||||
|
||||
else if (rxd_bit_ctr_inc) begin
|
||||
rxd_bit_ctr_new = rxd_bit_ctr_reg + 1'h1;
|
||||
rxd_bit_ctr_we = 1'b1;
|
||||
end
|
||||
end // rxd_bit_ctr
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// rxd_bitrate_ctr
|
||||
//
|
||||
// Bitrate counter for receiving data on the external
|
||||
// serial interface.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin: rxd_bitrate_ctr
|
||||
rxd_bitrate_ctr_new = 16'h0;
|
||||
rxd_bitrate_ctr_we = 1'h0;
|
||||
|
||||
if (rxd_bitrate_ctr_rst) begin
|
||||
rxd_bitrate_ctr_new = 16'h0;
|
||||
rxd_bitrate_ctr_we = 1'b1;
|
||||
end
|
||||
|
||||
else if (rxd_bitrate_ctr_inc) begin
|
||||
rxd_bitrate_ctr_new = rxd_bitrate_ctr_reg + 1'h1;
|
||||
rxd_bitrate_ctr_we = 1'b1;
|
||||
end
|
||||
end // rxd_bitrate_ctr
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// txd_bit_ctr
|
||||
//
|
||||
// Bit counter for transmitting data on the external
|
||||
// serial interface.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin: txd_bit_ctr
|
||||
txd_bit_ctr_new = 5'h0;
|
||||
txd_bit_ctr_we = 1'h0;
|
||||
|
||||
if (txd_bit_ctr_rst) begin
|
||||
txd_bit_ctr_new = 5'h0;
|
||||
txd_bit_ctr_we = 1'h1;
|
||||
end
|
||||
|
||||
else if (txd_bit_ctr_inc) begin
|
||||
txd_bit_ctr_new = txd_bit_ctr_reg + 1'h1;
|
||||
txd_bit_ctr_we = 1'b1;
|
||||
end
|
||||
end // txd_bit_ctr
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// txd_bitrate_ctr
|
||||
//
|
||||
// Bitrate counter for transmitting data on the external
|
||||
// serial interface.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin: txd_bitrate_ctr
|
||||
txd_bitrate_ctr_new = 16'h0;
|
||||
txd_bitrate_ctr_we = 0;
|
||||
|
||||
if (txd_bitrate_ctr_rst) begin
|
||||
txd_bitrate_ctr_new = 16'h0;
|
||||
txd_bitrate_ctr_we = 1;
|
||||
end
|
||||
|
||||
else if (txd_bitrate_ctr_inc) begin
|
||||
txd_bitrate_ctr_new = txd_bitrate_ctr_reg + 1'h1;
|
||||
txd_bitrate_ctr_we = 1;
|
||||
end
|
||||
end // txd_bitrate_ctr
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// external_rx_engine
|
||||
//
|
||||
// Logic that implements the receive engine towards
|
||||
// the external interface. Detects incoming data, collects it,
|
||||
// if required checks parity and store correct data into
|
||||
// the rx buffer.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin: external_rx_engine
|
||||
rxd_bit_ctr_rst = 0;
|
||||
rxd_bit_ctr_inc = 0;
|
||||
rxd_bitrate_ctr_rst = 0;
|
||||
rxd_bitrate_ctr_inc = 0;
|
||||
rxd_byte_we = 0;
|
||||
rxd_syn_new = 0;
|
||||
rxd_syn_we = 0;
|
||||
erx_ctrl_new = ERX_IDLE;
|
||||
erx_ctrl_we = 0;
|
||||
|
||||
case (erx_ctrl_reg)
|
||||
ERX_IDLE: begin
|
||||
if (!rxd_reg) begin
|
||||
// Possible start bit detected.
|
||||
rxd_bitrate_ctr_rst = 1;
|
||||
erx_ctrl_new = ERX_START;
|
||||
erx_ctrl_we = 1;
|
||||
end
|
||||
end
|
||||
|
||||
ERX_START: begin
|
||||
rxd_bitrate_ctr_inc = 1;
|
||||
if (rxd_reg) begin
|
||||
// Just a glitch.
|
||||
erx_ctrl_new = ERX_IDLE;
|
||||
erx_ctrl_we = 1;
|
||||
end
|
||||
|
||||
else begin
|
||||
if (rxd_bitrate_ctr_reg == half_bit_rate) begin
|
||||
// start bit assumed. We start sampling data.
|
||||
rxd_bit_ctr_rst = 1;
|
||||
rxd_bitrate_ctr_rst = 1;
|
||||
erx_ctrl_new = ERX_BITS;
|
||||
erx_ctrl_we = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ERX_BITS: begin
|
||||
if (rxd_bitrate_ctr_reg < bit_rate) begin
|
||||
rxd_bitrate_ctr_inc = 1;
|
||||
end
|
||||
|
||||
else begin
|
||||
rxd_byte_we = 1;
|
||||
rxd_bit_ctr_inc = 1;
|
||||
rxd_bitrate_ctr_rst = 1;
|
||||
if (rxd_bit_ctr_reg == data_bits - 1) begin
|
||||
erx_ctrl_new = ERX_STOP;
|
||||
erx_ctrl_we = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ERX_STOP: begin
|
||||
rxd_bitrate_ctr_inc = 1;
|
||||
if (rxd_bitrate_ctr_reg == bit_rate * stop_bits) begin
|
||||
rxd_syn_new = 1;
|
||||
rxd_syn_we = 1;
|
||||
erx_ctrl_new = ERX_SYN;
|
||||
erx_ctrl_we = 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ERX_SYN: begin
|
||||
if (rxd_ack) begin
|
||||
rxd_syn_new = 0;
|
||||
rxd_syn_we = 1;
|
||||
erx_ctrl_new = ERX_IDLE;
|
||||
erx_ctrl_we = 1;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
end
|
||||
|
||||
endcase // case (erx_ctrl_reg)
|
||||
end // external_rx_engine
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// external_tx_engine
|
||||
//
|
||||
// Logic that implements the transmit engine towards
|
||||
// the external interface.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin: external_tx_engine
|
||||
txd_new = 0;
|
||||
txd_we = 0;
|
||||
txd_byte_new = 0;
|
||||
txd_byte_we = 0;
|
||||
txd_bit_ctr_rst = 0;
|
||||
txd_bit_ctr_inc = 0;
|
||||
txd_bitrate_ctr_rst = 0;
|
||||
txd_bitrate_ctr_inc = 0;
|
||||
txd_ready_new = 0;
|
||||
txd_ready_we = 0;
|
||||
etx_ctrl_new = ETX_IDLE;
|
||||
etx_ctrl_we = 0;
|
||||
|
||||
case (etx_ctrl_reg)
|
||||
ETX_IDLE: begin
|
||||
txd_new = 1;
|
||||
txd_we = 1;
|
||||
if (txd_syn) begin
|
||||
txd_byte_new = txd_data;
|
||||
txd_byte_we = 1;
|
||||
txd_ready_new = 0;
|
||||
txd_ready_we = 1;
|
||||
txd_bitrate_ctr_rst = 1;
|
||||
etx_ctrl_new = ETX_ACK;
|
||||
etx_ctrl_we = 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ETX_ACK: begin
|
||||
if (!txd_syn) begin
|
||||
txd_new = 0;
|
||||
txd_we = 1;
|
||||
etx_ctrl_new = ETX_START;
|
||||
etx_ctrl_we = 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ETX_START: begin
|
||||
if (txd_bitrate_ctr_reg == bit_rate) begin
|
||||
txd_bit_ctr_rst = 1;
|
||||
etx_ctrl_new = ETX_BITS;
|
||||
etx_ctrl_we = 1;
|
||||
end
|
||||
|
||||
else begin
|
||||
txd_bitrate_ctr_inc = 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ETX_BITS: begin
|
||||
if (txd_bitrate_ctr_reg < bit_rate) begin
|
||||
txd_bitrate_ctr_inc = 1;
|
||||
end
|
||||
|
||||
else begin
|
||||
txd_bitrate_ctr_rst = 1;
|
||||
if (txd_bit_ctr_reg == data_bits) begin
|
||||
txd_new = 1;
|
||||
txd_we = 1;
|
||||
etx_ctrl_new = ETX_STOP;
|
||||
etx_ctrl_we = 1;
|
||||
end
|
||||
|
||||
else begin
|
||||
txd_new = txd_byte_reg[txd_bit_ctr_reg];
|
||||
txd_we = 1;
|
||||
txd_bit_ctr_inc = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ETX_STOP: begin
|
||||
txd_bitrate_ctr_inc = 1;
|
||||
if (txd_bitrate_ctr_reg == bit_rate * stop_bits) begin
|
||||
txd_ready_new = 1;
|
||||
txd_ready_we = 1;
|
||||
etx_ctrl_new = ETX_IDLE;
|
||||
etx_ctrl_we = 1;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
end
|
||||
|
||||
endcase // case (etx_ctrl_reg)
|
||||
end // external_tx_engine
|
||||
|
||||
endmodule // uart
|
||||
|
||||
//======================================================================
|
||||
// EOF uart.v
|
||||
//======================================================================
|
179
hw/application_fpga/core/uart/rtl/uart_fifo.v
Normal file
179
hw/application_fpga/core/uart/rtl/uart_fifo.v
Normal file
|
@ -0,0 +1,179 @@
|
|||
//======================================================================
|
||||
//
|
||||
// uart_fifo.v
|
||||
// -----------
|
||||
// FIFO for rx and tx data buffering in the UART.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (c) 2022, Tillitis AB
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or
|
||||
// without modification, are permitted provided that the following
|
||||
// conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module uart_fifo(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire in_syn,
|
||||
input wire [7 : 0] in_data,
|
||||
output wire in_ack,
|
||||
|
||||
output wire out_syn,
|
||||
output wire [7 : 0] out_data,
|
||||
input wire out_ack
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg [7 : 0] fifo_mem [0 : 255];
|
||||
reg fifo_mem_we;
|
||||
|
||||
reg [7: 0] in_ptr_reg;
|
||||
reg [7: 0] in_ptr_new;
|
||||
reg in_ptr_inc;
|
||||
reg in_ptr_we;
|
||||
|
||||
reg [7: 0] out_ptr_reg;
|
||||
reg [7: 0] out_ptr_new;
|
||||
reg out_ptr_inc;
|
||||
reg out_ptr_we;
|
||||
|
||||
reg [7: 0] byte_ctr_reg;
|
||||
reg [7: 0] byte_ctr_new;
|
||||
reg byte_ctr_inc;
|
||||
reg byte_ctr_dec;
|
||||
reg byte_ctr_we;
|
||||
|
||||
reg in_ack_reg;
|
||||
reg in_ack_new;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign in_ack = in_ack_reg;
|
||||
|
||||
assign out_syn = |byte_ctr_reg;
|
||||
assign out_data = fifo_mem[out_ptr_reg];
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin: reg_update
|
||||
if (!reset_n) begin
|
||||
in_ptr_reg <= 8'h0;
|
||||
out_ptr_reg <= 8'h0;
|
||||
byte_ctr_reg <= 8'h0;
|
||||
in_ack_reg <= 1'h0;
|
||||
end
|
||||
else begin
|
||||
in_ack_reg <= in_ack_new;
|
||||
|
||||
if (fifo_mem_we) begin
|
||||
fifo_mem[in_ptr_reg] <= in_data;
|
||||
end
|
||||
|
||||
if (in_ptr_we) begin
|
||||
in_ptr_reg <= in_ptr_new;
|
||||
end
|
||||
|
||||
if (out_ptr_we) begin
|
||||
out_ptr_reg <= out_ptr_new;
|
||||
end
|
||||
|
||||
if (byte_ctr_we) begin
|
||||
byte_ctr_reg <= byte_ctr_new;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// byte_ctr
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : byte_ctr
|
||||
byte_ctr_new = 8'h0;
|
||||
byte_ctr_we = 1'h0;
|
||||
|
||||
if ((byte_ctr_inc) && (!byte_ctr_dec)) begin
|
||||
byte_ctr_new = byte_ctr_reg + 1'h1;
|
||||
byte_ctr_we = 1'h1;
|
||||
end
|
||||
|
||||
else if ((!byte_ctr_inc) && (byte_ctr_dec)) begin
|
||||
byte_ctr_new = byte_ctr_reg - 1'h1;
|
||||
byte_ctr_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// in_logic
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : in_logic
|
||||
fifo_mem_we = 1'h0;
|
||||
in_ack_new = 1'h0;
|
||||
byte_ctr_inc = 1'h0;
|
||||
in_ptr_new = in_ptr_reg + 1'h1;
|
||||
in_ptr_we = 1'h0;
|
||||
|
||||
if ((in_syn) && (!in_ack) && (byte_ctr_reg < 8'hff)) begin
|
||||
fifo_mem_we = 1'h1;
|
||||
in_ack_new = 1'h1;
|
||||
byte_ctr_inc = 1'h1;
|
||||
in_ptr_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// out_logic
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : out_logic
|
||||
byte_ctr_dec = 1'h0;
|
||||
out_ptr_new = out_ptr_reg + 1'h1;
|
||||
out_ptr_we = 1'h0;
|
||||
|
||||
if ((out_ack) && (byte_ctr_reg > 8'h0)) begin
|
||||
byte_ctr_dec = 1'h1;
|
||||
out_ptr_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // uart_fifo
|
||||
|
||||
//======================================================================
|
||||
// EOF uart_fifo.v
|
||||
//======================================================================
|
389
hw/application_fpga/core/uart/tb/tb_uart.v
Normal file
389
hw/application_fpga/core/uart/tb/tb_uart.v
Normal file
|
@ -0,0 +1,389 @@
|
|||
//======================================================================
|
||||
//
|
||||
// tb_uart.v
|
||||
// ---------
|
||||
// Testbench for the UART core.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (c) 2014, Secworks Sweden AB
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or
|
||||
// without modification, are permitted provided that the following
|
||||
// conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in
|
||||
// the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
module tb_uart();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
parameter DEBUG = 0;
|
||||
parameter VERBOSE = 0;
|
||||
|
||||
parameter CLK_HALF_PERIOD = 1;
|
||||
parameter CLK_PERIOD = CLK_HALF_PERIOD * 2;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Register and Wire declarations.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] cycle_ctr;
|
||||
reg [31 : 0] error_ctr;
|
||||
reg [31 : 0] tc_ctr;
|
||||
|
||||
reg tb_clk;
|
||||
reg tb_reset_n;
|
||||
reg tb_rxd;
|
||||
wire tb_txd;
|
||||
wire tb_rxd_syn;
|
||||
wire [7 : 0] tb_rxd_data;
|
||||
wire tb_rxd_ack;
|
||||
wire tb_txd_syn;
|
||||
wire [7 : 0] tb_txd_data;
|
||||
wire tb_txd_ack;
|
||||
reg tb_cs;
|
||||
reg tb_we;
|
||||
reg [7 : 0] tb_address;
|
||||
reg [31 : 0] tb_write_data;
|
||||
wire [31 : 0] tb_read_data;
|
||||
wire tb_error;
|
||||
wire [7 : 0] tb_debug;
|
||||
|
||||
reg txd_state;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Device Under Test.
|
||||
//----------------------------------------------------------------
|
||||
uart dut(
|
||||
.clk(tb_clk),
|
||||
.reset_n(tb_reset_n),
|
||||
|
||||
.rxd(tb_rxd),
|
||||
.txd(tb_txd),
|
||||
|
||||
.rxd_syn(tb_rxd_syn),
|
||||
.rxd_data(tb_rxd_data),
|
||||
.rxd_ack(tb_rxd_ack),
|
||||
|
||||
// Internal transmit interface.
|
||||
.txd_syn(tb_txd_syn),
|
||||
.txd_data(tb_txd_data),
|
||||
.txd_ack(tb_txd_ack),
|
||||
|
||||
// API interface.
|
||||
.cs(tb_cs),
|
||||
.we(tb_we),
|
||||
.address(tb_address),
|
||||
.write_data(tb_write_data),
|
||||
.read_data(tb_read_data),
|
||||
.error(tb_error),
|
||||
|
||||
.debug(tb_debug)
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent assignments.
|
||||
//----------------------------------------------------------------
|
||||
// We connect the internal facing ports on the dut together.
|
||||
assign tb_txd_syn = tb_rxd_syn;
|
||||
assign tb_txd_data = tb_rxd_data;
|
||||
assign tb_rxd_ack = tb_txd_ack;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// clk_gen
|
||||
//
|
||||
// Clock generator process.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : clk_gen
|
||||
#CLK_HALF_PERIOD tb_clk = !tb_clk;
|
||||
end // clk_gen
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// sys_monitor
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : sys_monitor
|
||||
#(CLK_PERIOD);
|
||||
if (DEBUG)
|
||||
begin
|
||||
dump_rx_state();
|
||||
dump_tx_state();
|
||||
$display("");
|
||||
end
|
||||
if (VERBOSE)
|
||||
begin
|
||||
$display("cycle: 0x%016x", cycle_ctr);
|
||||
end
|
||||
cycle_ctr = cycle_ctr + 1;
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// tx_monitor
|
||||
//
|
||||
// Observes what happens on the dut tx port and reports it.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : tx_monitor
|
||||
if ((!tb_txd) && txd_state)
|
||||
begin
|
||||
$display("txd going low.");
|
||||
txd_state = 0;
|
||||
end
|
||||
|
||||
if (tb_txd && (!txd_state))
|
||||
begin
|
||||
$display("txd going high");
|
||||
txd_state = 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// dump_dut_state()
|
||||
//
|
||||
// Dump the state of the dut when needed.
|
||||
//----------------------------------------------------------------
|
||||
task dump_dut_state;
|
||||
begin
|
||||
$display("State of DUT");
|
||||
$display("------------");
|
||||
$display("Inputs and outputs:");
|
||||
$display("rxd = 0x%01x, txd = 0x%01x,",
|
||||
dut.core.rxd, dut.core.txd);
|
||||
$display("");
|
||||
|
||||
$display("Sample and data registers:");
|
||||
$display("rxd_reg = 0x%01x, rxd_byte_reg = 0x%01x",
|
||||
dut.core.rxd_reg, dut.core.rxd_byte_reg);
|
||||
$display("");
|
||||
|
||||
$display("Counters:");
|
||||
$display("rxd_bit_ctr_reg = 0x%01x, rxd_bitrate_ctr_reg = 0x%02x",
|
||||
dut.core.rxd_bit_ctr_reg, dut.core.rxd_bitrate_ctr_reg);
|
||||
$display("");
|
||||
|
||||
|
||||
$display("Control signals and FSM state:");
|
||||
$display("erx_ctrl_reg = 0x%02x",
|
||||
dut.core.erx_ctrl_reg);
|
||||
$display("");
|
||||
end
|
||||
endtask // dump_dut_state
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// dump_rx_state()
|
||||
//
|
||||
// Dump the state of the rx engine.
|
||||
//----------------------------------------------------------------
|
||||
task dump_rx_state;
|
||||
begin
|
||||
$display("rxd = 0x%01x, rxd_reg = 0x%01x, rxd_byte_reg = 0x%01x, rxd_bit_ctr_reg = 0x%01x, rxd_bitrate_ctr_reg = 0x%02x, rxd_syn = 0x%01x, erx_ctrl_reg = 0x%02x",
|
||||
dut.core.rxd, dut.core.rxd_reg, dut.core.rxd_byte_reg, dut.core.rxd_bit_ctr_reg,
|
||||
dut.core.rxd_bitrate_ctr_reg, dut.core.rxd_syn, dut.core.erx_ctrl_reg);
|
||||
end
|
||||
endtask // dump_dut_state
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// dump_tx_state()
|
||||
//
|
||||
// Dump the state of the tx engine.
|
||||
//----------------------------------------------------------------
|
||||
task dump_tx_state;
|
||||
begin
|
||||
$display("txd = 0x%01x, txd_reg = 0x%01x, txd_byte_reg = 0x%01x, txd_bit_ctr_reg = 0x%01x, txd_bitrate_ctr_reg = 0x%02x, txd_ack = 0x%01x, etx_ctrl_reg = 0x%02x",
|
||||
dut.core.txd, dut.core.txd_reg, dut.core.txd_byte_reg, dut.core.txd_bit_ctr_reg,
|
||||
dut.core.txd_bitrate_ctr_reg, dut.core.txd_ack, dut.core.etx_ctrl_reg);
|
||||
end
|
||||
endtask // dump_dut_state
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reset_dut()
|
||||
//----------------------------------------------------------------
|
||||
task reset_dut;
|
||||
begin
|
||||
$display("*** Toggle reset.");
|
||||
tb_reset_n = 0;
|
||||
#(2 * CLK_PERIOD);
|
||||
tb_reset_n = 1;
|
||||
end
|
||||
endtask // reset_dut
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// init_sim()
|
||||
//
|
||||
// Initialize all counters and testbed functionality as well
|
||||
// as setting the DUT inputs to defined values.
|
||||
//----------------------------------------------------------------
|
||||
task init_sim;
|
||||
begin
|
||||
cycle_ctr = 0;
|
||||
error_ctr = 0;
|
||||
tc_ctr = 0;
|
||||
|
||||
tb_clk = 0;
|
||||
tb_reset_n = 1;
|
||||
tb_rxd = 1;
|
||||
tb_cs = 0;
|
||||
tb_we = 0;
|
||||
tb_address = 8'h00;
|
||||
tb_write_data = 32'h00000000;
|
||||
|
||||
txd_state = 1;
|
||||
end
|
||||
endtask // init_sim
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// transmit_byte
|
||||
//
|
||||
// Transmit a byte of data to the DUT receive port.
|
||||
//----------------------------------------------------------------
|
||||
task transmit_byte(input [7 : 0] data);
|
||||
integer i;
|
||||
begin
|
||||
$display("*** Transmitting byte 0x%02x to the dut.", data);
|
||||
|
||||
#10;
|
||||
|
||||
// Start bit
|
||||
$display("*** Transmitting start bit.");
|
||||
tb_rxd = 0;
|
||||
#(CLK_PERIOD * dut.DEFAULT_BIT_RATE);
|
||||
|
||||
// Send the bits LSB first.
|
||||
for (i = 0 ; i < 8 ; i = i + 1)
|
||||
begin
|
||||
$display("*** Transmitting data[%1d] = 0x%01x.", i, data[i]);
|
||||
tb_rxd = data[i];
|
||||
#(CLK_PERIOD * dut.DEFAULT_BIT_RATE);
|
||||
end
|
||||
|
||||
// Send two stop bits. I.e. two bit times high (mark) value.
|
||||
$display("*** Transmitting two stop bits.");
|
||||
tb_rxd = 1;
|
||||
#(2 * CLK_PERIOD * dut.DEFAULT_BIT_RATE * dut.DEFAULT_STOP_BITS);
|
||||
$display("*** End of transmission.");
|
||||
end
|
||||
endtask // transmit_byte
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// check_transmit
|
||||
//
|
||||
// Transmits a byte and checks that it was captured internally
|
||||
// by the dut.
|
||||
//----------------------------------------------------------------
|
||||
task check_transmit(input [7 : 0] data);
|
||||
begin
|
||||
tc_ctr = tc_ctr + 1;
|
||||
|
||||
transmit_byte(data);
|
||||
|
||||
if (dut.core.rxd_byte_reg == data)
|
||||
begin
|
||||
$display("*** Correct data: 0x%01x captured by the dut.",
|
||||
dut.core.rxd_byte_reg);
|
||||
end
|
||||
else
|
||||
begin
|
||||
$display("*** Incorrect data: 0x%01x captured by the dut Should be: 0x%01x.",
|
||||
dut.core.rxd_byte_reg, data);
|
||||
error_ctr = error_ctr + 1;
|
||||
end
|
||||
end
|
||||
endtask // check_transmit
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// test_transmit
|
||||
//
|
||||
// Transmit a number of test bytes to the dut.
|
||||
//----------------------------------------------------------------
|
||||
task test_transmit;
|
||||
begin
|
||||
check_transmit(8'h55);
|
||||
check_transmit(8'h42);
|
||||
check_transmit(8'hde);
|
||||
check_transmit(8'had);
|
||||
end
|
||||
endtask // test_transmit
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// display_test_result()
|
||||
//
|
||||
// Display the accumulated test results.
|
||||
//----------------------------------------------------------------
|
||||
task display_test_result;
|
||||
begin
|
||||
if (error_ctr == 0)
|
||||
begin
|
||||
$display("*** All %02d test cases completed successfully", tc_ctr);
|
||||
end
|
||||
else
|
||||
begin
|
||||
$display("*** %02d test cases did not complete successfully.", error_ctr);
|
||||
end
|
||||
end
|
||||
endtask // display_test_result
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// uart_test
|
||||
// The main test functionality.
|
||||
//----------------------------------------------------------------
|
||||
initial
|
||||
begin : uart_test
|
||||
$display(" -- Testbench for uart core started --");
|
||||
|
||||
init_sim();
|
||||
dump_dut_state();
|
||||
reset_dut();
|
||||
dump_dut_state();
|
||||
|
||||
test_transmit();
|
||||
|
||||
display_test_result();
|
||||
$display("*** Simulation done.");
|
||||
$finish;
|
||||
end // uart_test
|
||||
endmodule // tb_uart
|
||||
|
||||
//======================================================================
|
||||
// EOF tb_uart.v
|
||||
//======================================================================
|
7
hw/application_fpga/core/uds/README.txt
Normal file
7
hw/application_fpga/core/uds/README.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
# uds
|
||||
|
||||
Unique Device Secret core
|
||||
|
||||
## Introduction
|
||||
This core store and protect the Unique Device Secret. The
|
||||
storage is implemented in discrete registers. The contents can be read once between chip reset, and only if the system is in not in application access mode.
|
129
hw/application_fpga/core/uds/rtl/uds.v
Normal file
129
hw/application_fpga/core/uds/rtl/uds.v
Normal file
|
@ -0,0 +1,129 @@
|
|||
//======================================================================
|
||||
//
|
||||
// uds.v
|
||||
// --------
|
||||
// Top level wrapper for the uds core.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module uds(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
output wire fw_app_mode,
|
||||
|
||||
input wire cs,
|
||||
input wire [7 : 0] address,
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_UDS_FIRST = 8'h10;
|
||||
localparam ADDR_UDS_LAST = 8'h17;
|
||||
|
||||
localparam CORE_NAME0 = 32'h7564735f; // "uds_"
|
||||
localparam CORE_NAME1 = 32'h6d656d20; // "mem "
|
||||
localparam CORE_VERSION = 32'h00000001;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers including update variables and write enable.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] uds_reg [0 : 7];
|
||||
initial $readmemh(`UDS_HEX, uds_reg);
|
||||
|
||||
reg uds_rd_reg [0 : 7];
|
||||
reg uds_rd_we;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] tmp_read_data;
|
||||
reg tmp_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent connectivity for ports etc.
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = tmp_read_data;
|
||||
assign ready = tmp_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//----------------------------------------------------------------
|
||||
always @ (posedge clk)
|
||||
begin : reg_update
|
||||
integer i;
|
||||
|
||||
if (!reset_n) begin
|
||||
for (i = 0 ; i < 8 ; i = i + 1) begin
|
||||
uds_rd_reg[i] <= 1'h0;;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (uds_rd_we) begin
|
||||
uds_rd_reg[address[2 : 0]] <= 1'h1;
|
||||
end
|
||||
end
|
||||
end // reg_update
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// api
|
||||
//
|
||||
// The interface command decoding logic.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : api
|
||||
uds_rd_we = 1'h0;
|
||||
tmp_read_data = 32'h0;
|
||||
tmp_ready = 1'h0;
|
||||
|
||||
if (cs) begin
|
||||
tmp_ready = 1'h1;
|
||||
|
||||
if (address == ADDR_NAME0) begin
|
||||
tmp_read_data = CORE_NAME0;
|
||||
end
|
||||
|
||||
if (address == ADDR_NAME1) begin
|
||||
tmp_read_data = CORE_NAME1;
|
||||
end
|
||||
|
||||
if (address == ADDR_VERSION) begin
|
||||
tmp_read_data = CORE_VERSION;
|
||||
end
|
||||
|
||||
if ((address >= ADDR_UDS_FIRST) && (address <= ADDR_UDS_LAST)) begin
|
||||
if (!fw_app_mode) begin
|
||||
if (uds_rd_reg[address[2 : 0]] == 1'h0) begin
|
||||
tmp_read_data = uds_reg[address[2 : 0]];
|
||||
uds_rd_we = 1'h1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // uds
|
||||
|
||||
//======================================================================
|
||||
// EOF uds.v
|
||||
//======================================================================
|
300
hw/application_fpga/core/uds/tb/tb_uds.v
Normal file
300
hw/application_fpga/core/uds/tb/tb_uds.v
Normal file
|
@ -0,0 +1,300 @@
|
|||
//======================================================================
|
||||
//
|
||||
// tb_uds.v
|
||||
// -----------
|
||||
// Testbench for the UDS core.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module tb_uds();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Internal constant and parameter definitions.
|
||||
//----------------------------------------------------------------
|
||||
parameter DEBUG = 1;
|
||||
parameter DUMP_WAIT = 0;
|
||||
|
||||
parameter CLK_HALF_PERIOD = 1;
|
||||
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
|
||||
|
||||
localparam ADDR_NAME0 = 8'h00;
|
||||
localparam ADDR_NAME1 = 8'h01;
|
||||
localparam ADDR_VERSION = 8'h02;
|
||||
|
||||
localparam ADDR_UDS_FIRST = 8'h10;
|
||||
localparam ADDR_UDS_LAST = 8'h17;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Register and Wire declarations.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] cycle_ctr;
|
||||
reg [31 : 0] error_ctr;
|
||||
reg [31 : 0] tc_ctr;
|
||||
reg tb_monitor;
|
||||
|
||||
reg tb_clk;
|
||||
reg tb_reset_n;
|
||||
reg tb_cs;
|
||||
reg [7 : 0] tb_address;
|
||||
wire [31 : 0] tb_read_data;
|
||||
|
||||
reg [31 : 0] read_data;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Device Under Test.
|
||||
//----------------------------------------------------------------
|
||||
uds dut(
|
||||
.clk(tb_clk),
|
||||
.reset_n(tb_reset_n),
|
||||
|
||||
.cs(tb_cs),
|
||||
|
||||
.address(tb_address),
|
||||
.read_data(tb_read_data)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// clk_gen
|
||||
//
|
||||
// Always running clock generator process.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : clk_gen
|
||||
#CLK_HALF_PERIOD;
|
||||
tb_clk = !tb_clk;
|
||||
end // clk_gen
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// sys_monitor()
|
||||
//
|
||||
// An always running process that creates a cycle counter and
|
||||
// conditionally displays information about the DUT.
|
||||
//----------------------------------------------------------------
|
||||
always
|
||||
begin : sys_monitor
|
||||
cycle_ctr = cycle_ctr + 1;
|
||||
#(CLK_PERIOD);
|
||||
if (tb_monitor)
|
||||
begin
|
||||
dump_dut_state();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// dump_dut_state()
|
||||
//
|
||||
// Dump the state of the dump when needed.
|
||||
//----------------------------------------------------------------
|
||||
task dump_dut_state;
|
||||
begin : dump_dut_state
|
||||
integer i;
|
||||
$display("State of DUT");
|
||||
$display("------------");
|
||||
$display("Cycle: %08d", cycle_ctr);
|
||||
for (i = 0 ; i < 8 ; i = i + 1) begin
|
||||
$display("uds_reg[%1d]: 0x%08x, uds_rd_reg[%1d]: 0x%1x",
|
||||
i, dut.uds_reg[i], i, dut.uds_rd_reg[i]);
|
||||
end
|
||||
$display("");
|
||||
$display("");
|
||||
end
|
||||
endtask // dump_dut_state
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reset_dut()
|
||||
//
|
||||
// Toggle reset to put the DUT into a well known state.
|
||||
//----------------------------------------------------------------
|
||||
task reset_dut;
|
||||
begin
|
||||
$display("--- Toggle reset.");
|
||||
tb_reset_n = 0;
|
||||
#(2 * CLK_PERIOD);
|
||||
tb_reset_n = 1;
|
||||
end
|
||||
endtask // reset_dut
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// display_test_result()
|
||||
//
|
||||
// Display the accumulated test results.
|
||||
//----------------------------------------------------------------
|
||||
task display_test_result;
|
||||
begin
|
||||
if (error_ctr == 0)
|
||||
begin
|
||||
$display("--- All %02d test cases completed successfully", tc_ctr);
|
||||
end
|
||||
else
|
||||
begin
|
||||
$display("--- %02d tests completed - %02d test cases did not complete successfully.",
|
||||
tc_ctr, error_ctr);
|
||||
end
|
||||
end
|
||||
endtask // display_test_result
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// init_sim()
|
||||
//
|
||||
// Initialize all counters and testbed functionality as well
|
||||
// as setting the DUT inputs to defined values.
|
||||
//----------------------------------------------------------------
|
||||
task init_sim;
|
||||
begin
|
||||
cycle_ctr = 0;
|
||||
error_ctr = 0;
|
||||
tc_ctr = 0;
|
||||
tb_monitor = 0;
|
||||
|
||||
tb_clk = 1'h0;
|
||||
tb_reset_n = 1'h1;
|
||||
tb_cs = 1'h0;
|
||||
tb_address = 8'h0;
|
||||
end
|
||||
endtask // init_sim
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// read_word()
|
||||
//
|
||||
// Read a data word from the given address in the DUT.
|
||||
// the word read will be available in the global variable
|
||||
// read_data.
|
||||
//----------------------------------------------------------------
|
||||
task read_word(input [11 : 0] address);
|
||||
begin
|
||||
tb_address = address;
|
||||
tb_cs = 1;
|
||||
#(CLK_PERIOD);
|
||||
read_data = tb_read_data;
|
||||
tb_cs = 0;
|
||||
|
||||
if (DEBUG)
|
||||
begin
|
||||
$display("--- Reading 0x%08x from 0x%02x.", read_data, address);
|
||||
$display("");
|
||||
end
|
||||
end
|
||||
endtask // read_word
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// test1()
|
||||
//----------------------------------------------------------------
|
||||
task test1;
|
||||
begin
|
||||
tc_ctr = tc_ctr + 1;
|
||||
tb_monitor = 1'h0;
|
||||
|
||||
$display("");
|
||||
$display("--- test1: started.");
|
||||
|
||||
$display("--- test1: Reading NAME and version info.");
|
||||
read_word(ADDR_NAME0);
|
||||
read_word(ADDR_NAME1);
|
||||
read_word(ADDR_VERSION);
|
||||
|
||||
$display("--- test1: Dumping DUT state to show UDS contents");
|
||||
dump_dut_state();
|
||||
|
||||
$display("--- test1: Reading UDS words.");
|
||||
read_word(ADDR_UDS_FIRST + 0);
|
||||
read_word(ADDR_UDS_FIRST + 1);
|
||||
read_word(ADDR_UDS_FIRST + 2);
|
||||
|
||||
$display("--- test1: Dumping state again to see read bits.");
|
||||
dump_dut_state();
|
||||
|
||||
$display("--- test1: Reading rest of the words.");
|
||||
read_word(ADDR_UDS_FIRST + 3);
|
||||
read_word(ADDR_UDS_FIRST + 4);
|
||||
read_word(ADDR_UDS_FIRST + 5);
|
||||
read_word(ADDR_UDS_FIRST + 6);
|
||||
read_word(ADDR_UDS_FIRST + 7);
|
||||
|
||||
$display("--- test1: Dumping state again to see read bits.");
|
||||
dump_dut_state();
|
||||
|
||||
$display("--- test1: Reading UDS words again.");
|
||||
read_word(ADDR_UDS_FIRST + 0);
|
||||
read_word(ADDR_UDS_FIRST + 1);
|
||||
read_word(ADDR_UDS_FIRST + 2);
|
||||
read_word(ADDR_UDS_FIRST + 3);
|
||||
read_word(ADDR_UDS_FIRST + 4);
|
||||
read_word(ADDR_UDS_FIRST + 5);
|
||||
read_word(ADDR_UDS_FIRST + 6);
|
||||
read_word(ADDR_UDS_FIRST + 7);
|
||||
|
||||
$display("--- test1: Resetting DUT.");
|
||||
reset_dut();
|
||||
|
||||
$display("--- test1: Dumping state again to see read bits.");
|
||||
dump_dut_state();
|
||||
|
||||
$display("--- test1: Reading UDS words.");
|
||||
read_word(ADDR_UDS_FIRST + 0);
|
||||
read_word(ADDR_UDS_FIRST + 1);
|
||||
read_word(ADDR_UDS_FIRST + 2);
|
||||
read_word(ADDR_UDS_FIRST + 3);
|
||||
read_word(ADDR_UDS_FIRST + 4);
|
||||
read_word(ADDR_UDS_FIRST + 5);
|
||||
read_word(ADDR_UDS_FIRST + 6);
|
||||
read_word(ADDR_UDS_FIRST + 7);
|
||||
|
||||
$display("--- test1: Reading UDS words again.");
|
||||
read_word(ADDR_UDS_FIRST + 0);
|
||||
read_word(ADDR_UDS_FIRST + 1);
|
||||
read_word(ADDR_UDS_FIRST + 2);
|
||||
read_word(ADDR_UDS_FIRST + 3);
|
||||
read_word(ADDR_UDS_FIRST + 4);
|
||||
read_word(ADDR_UDS_FIRST + 5);
|
||||
read_word(ADDR_UDS_FIRST + 6);
|
||||
read_word(ADDR_UDS_FIRST + 7);
|
||||
|
||||
$display("--- test1: completed.");
|
||||
$display("");
|
||||
end
|
||||
endtask // tes1
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// uds_test
|
||||
//----------------------------------------------------------------
|
||||
initial
|
||||
begin : uds_test
|
||||
$display("");
|
||||
$display(" -= Testbench for uds started =-");
|
||||
$display(" ===========================");
|
||||
$display("");
|
||||
|
||||
init_sim();
|
||||
reset_dut();
|
||||
test1();
|
||||
|
||||
display_test_result();
|
||||
$display("");
|
||||
$display(" -= Testbench for uds started =-");
|
||||
$display(" ===========================");
|
||||
$display("");
|
||||
$finish;
|
||||
end // uds_test
|
||||
endmodule // tb_uds
|
||||
|
||||
//======================================================================
|
||||
// EOF tb_uds.v
|
||||
//======================================================================
|
55
hw/application_fpga/core/uds/toolruns/Makefile
Executable file
55
hw/application_fpga/core/uds/toolruns/Makefile
Executable file
|
@ -0,0 +1,55 @@
|
|||
#===================================================================
|
||||
#
|
||||
# Makefile
|
||||
# --------
|
||||
# Makefile for building the UDS core.
|
||||
#
|
||||
#
|
||||
# Author: Joachim Strombergson
|
||||
# Copyright (C) 2022 - Tillitis AB
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
#===================================================================
|
||||
|
||||
TOP_SRC=../rtl/uds.v
|
||||
TB_TOP_SRC =../tb/tb_uds.v
|
||||
|
||||
CC = iverilog
|
||||
CC_FLAGS = -Wall
|
||||
|
||||
LINT = verilator
|
||||
LINT_FLAGS = +1364-2001ext+ --lint-only -Wall -Wno-fatal -Wno-DECLFILENAME
|
||||
|
||||
|
||||
all: top.sim
|
||||
|
||||
|
||||
top.sim: $(TB_TOP_SRC) $(TOP_SRC)
|
||||
$(CC) $(CC_FLAGS) -o top.sim $(TB_TOP_SRC) $(TOP_SRC)
|
||||
|
||||
|
||||
sim-top: top.sim
|
||||
./top.sim
|
||||
|
||||
|
||||
lint-top: $(TOP_SRC)
|
||||
$(LINT) $(LINT_FLAGS) $(TOP_SRC)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f top.sim
|
||||
|
||||
|
||||
help:
|
||||
@echo "Build system for simulation of UDS core"
|
||||
@echo ""
|
||||
@echo "Supported targets:"
|
||||
@echo "------------------"
|
||||
@echo "top.sim: Build top level simulation target."
|
||||
@echo "sim-top: Run top level simulation."
|
||||
@echo "lint-top: Lint top rtl source files."
|
||||
@echo "clean: Delete all built files."
|
||||
|
||||
#===================================================================
|
||||
# EOF Makefile
|
||||
#===================================================================
|
39
hw/application_fpga/data/application_fpga_mta1_usb_dev.pcf
Normal file
39
hw/application_fpga/data/application_fpga_mta1_usb_dev.pcf
Normal file
|
@ -0,0 +1,39 @@
|
|||
#=======================================================================
|
||||
#
|
||||
# application_fpga_mta1_usb_dev.pcf
|
||||
# ---------------------------------
|
||||
# Pin constraints file for the Application FPGA design used on the
|
||||
# Mullvad MTA1_USB_DEV board.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 2022 - Tillitis AB
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
#=======================================================================
|
||||
|
||||
# UART.
|
||||
set_io interface_rx 15
|
||||
set_io interface_tx 16
|
||||
#set_io interface_cts 27
|
||||
#set_io interface_rts 28
|
||||
|
||||
|
||||
# Touch sense, mapped to a switch.
|
||||
set_io touch_event 23
|
||||
|
||||
|
||||
# GPIOs.
|
||||
set_io app_gpio1 26
|
||||
set_io app_gpio2 27
|
||||
set_io app_gpio3 31
|
||||
set_io app_gpio4 32
|
||||
|
||||
|
||||
# LEDs
|
||||
set_io led_r 41
|
||||
set_io led_g 40
|
||||
set_io led_b 39
|
||||
|
||||
#=======================================================================
|
||||
# EOF application_fpga_usb_dev.pcf
|
||||
#=======================================================================
|
39
hw/application_fpga/data/application_fpga_mta1_usb_v1.pcf
Normal file
39
hw/application_fpga/data/application_fpga_mta1_usb_v1.pcf
Normal file
|
@ -0,0 +1,39 @@
|
|||
#=======================================================================
|
||||
#
|
||||
# application_fpga_usb_v1.pcf
|
||||
# ---------------------------
|
||||
# Pin constraints file for the Application FPGA design to be used
|
||||
# on the MTA1-USB-V1 board with the CH552 MCU used as a USB-serial chip.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 2022 - Tillitis AB
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
#=======================================================================
|
||||
|
||||
# UART.
|
||||
set_io interface_rx 26
|
||||
set_io interface_tx 25
|
||||
# set_io interface_cts 27
|
||||
# set_io interface_rts 28
|
||||
|
||||
|
||||
# Touch sense.
|
||||
set_io touch_event 6
|
||||
|
||||
|
||||
# GPIOs.
|
||||
set_io app_gpio1 36
|
||||
set_io app_gpio2 38
|
||||
set_io app_gpio3 45
|
||||
set_io app_gpio4 46
|
||||
|
||||
|
||||
# LEDs
|
||||
set_io led_r 39
|
||||
set_io led_g 40
|
||||
set_io led_b 41
|
||||
|
||||
#=======================================================================
|
||||
# EOF application_fpga_ch552.pcf
|
||||
#=======================================================================
|
2
hw/application_fpga/data/udi.hex
Normal file
2
hw/application_fpga/data/udi.hex
Normal file
|
@ -0,0 +1,2 @@
|
|||
00010203
|
||||
04050607
|
8
hw/application_fpga/data/uds.hex
Normal file
8
hw/application_fpga/data/uds.hex
Normal file
|
@ -0,0 +1,8 @@
|
|||
80808080
|
||||
91919191
|
||||
a2a2a2a2
|
||||
b3b3b3b3
|
||||
c4c4c4c4
|
||||
d5d5d5d5
|
||||
e6e6e6e6
|
||||
f7f7f7f7
|
15
hw/application_fpga/fw/.clang-format
Normal file
15
hw/application_fpga/fw/.clang-format
Normal file
|
@ -0,0 +1,15 @@
|
|||
BasedOnStyle: LLVM
|
||||
UseTab: Always
|
||||
IndentWidth: 8
|
||||
TabWidth: 8
|
||||
|
||||
IncludeBlocks: Preserve
|
||||
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterFunction: true
|
||||
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
|
4
hw/application_fpga/fw/mta1_mkdf/Makefile
Normal file
4
hw/application_fpga/fw/mta1_mkdf/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
.PHONY: fmt
|
||||
fmt:
|
||||
# Uses ../.clang-format
|
||||
clang-format --verbose -i main.c lib.h lib.c proto.h proto.c types.h
|
53
hw/application_fpga/fw/mta1_mkdf/README.md
Normal file
53
hw/application_fpga/fw/mta1_mkdf/README.md
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Tillitis Key firmware
|
||||
|
||||
## Build the firmware
|
||||
|
||||
You need Clang with 32 bit RISC-V support. You can check this with:
|
||||
|
||||
```
|
||||
$ llc --version|grep riscv32
|
||||
riscv32 - 32-bit RISC-V
|
||||
```
|
||||
|
||||
or just try building.
|
||||
|
||||
Build the FPGA bitstream with the firmware using `make` in the
|
||||
`hw/application_fpga` directory.
|
||||
|
||||
If your available `objcopy` and `size` commands is anything other than
|
||||
the default `llvm-objcopy-14` and `llvm-size-14` define `OBJCOPY` and
|
||||
`SIZE` to whatever they're called on your system.
|
||||
|
||||
## Using QEMU
|
||||
|
||||
Checkout the `mta1` branch of [our version of the
|
||||
qemu](https://github.com/tillitis/qemu) and build:
|
||||
|
||||
```
|
||||
$ git clone -b mta1 https://github.com/tillitis/qemu
|
||||
$ mkdir qemu/build
|
||||
$ cd qemu/build
|
||||
$ ../configure --target-list=riscv32-softmmu
|
||||
$ make -j $(nproc)
|
||||
```
|
||||
|
||||
Run it like this:
|
||||
|
||||
```
|
||||
$ /path/to/qemu/build/qemu-system-riscv32 -nographic -M mta1_mkdf,fifo=chrid -bios firmware \
|
||||
-chardev pty,id=chrid
|
||||
```
|
||||
|
||||
This attaches the FIFO to a tty, something like `/dev/pts/16` which
|
||||
you can use with host software to talk to the firmware.
|
||||
|
||||
To quit QEMU you can use: `Ctrl-a x` (see `Ctrl-a ?` for other commands).
|
||||
|
||||
Debugging? Use the HTIF console by removing `-DNOCONSOLE` from the
|
||||
`CFLAGS` and using the helper functions in `lib.c` for printf-like
|
||||
debugging.
|
||||
|
||||
You can also use the qemu monitor for debugging, e.g. `info
|
||||
registers`, or run qemu with `-d in_asm` or `-d trace:riscv_trap`.
|
||||
|
||||
Happy hacking!
|
116
hw/application_fpga/fw/mta1_mkdf/blake2s/LICENSE
Normal file
116
hw/application_fpga/fw/mta1_mkdf/blake2s/LICENSE
Normal file
|
@ -0,0 +1,116 @@
|
|||
CC0 1.0 Universal
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator and
|
||||
subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for the
|
||||
purpose of contributing to a commons of creative, cultural and scientific
|
||||
works ("Commons") that the public can reliably and without fear of later
|
||||
claims of infringement build upon, modify, incorporate in other works, reuse
|
||||
and redistribute as freely as possible in any form whatsoever and for any
|
||||
purposes, including without limitation commercial purposes. These owners may
|
||||
contribute to the Commons to promote the ideal of a free culture and the
|
||||
further production of creative, cultural and scientific works, or to gain
|
||||
reputation or greater distribution for their Work in part through the use and
|
||||
efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any expectation
|
||||
of additional consideration or compensation, the person associating CC0 with a
|
||||
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
|
||||
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
|
||||
and publicly distribute the Work under its terms, with knowledge of his or her
|
||||
Copyright and Related Rights in the Work and the meaning and intended legal
|
||||
effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not limited
|
||||
to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display, communicate,
|
||||
and translate a Work;
|
||||
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
|
||||
iii. publicity and privacy rights pertaining to a person's image or likeness
|
||||
depicted in a Work;
|
||||
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data in
|
||||
a Work;
|
||||
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation thereof,
|
||||
including any amended or successor version of such directive); and
|
||||
|
||||
vii. other similar, equivalent or corresponding rights throughout the world
|
||||
based on applicable law or treaty, and any national implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention of,
|
||||
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
|
||||
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
|
||||
and Related Rights and associated claims and causes of action, whether now
|
||||
known or unknown (including existing as well as future claims and causes of
|
||||
action), in the Work (i) in all territories worldwide, (ii) for the maximum
|
||||
duration provided by applicable law or treaty (including future time
|
||||
extensions), (iii) in any current or future medium and for any number of
|
||||
copies, and (iv) for any purpose whatsoever, including without limitation
|
||||
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
|
||||
the Waiver for the benefit of each member of the public at large and to the
|
||||
detriment of Affirmer's heirs and successors, fully intending that such Waiver
|
||||
shall not be subject to revocation, rescission, cancellation, termination, or
|
||||
any other legal or equitable action to disrupt the quiet enjoyment of the Work
|
||||
by the public as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason be
|
||||
judged legally invalid or ineffective under applicable law, then the Waiver
|
||||
shall be preserved to the maximum extent permitted taking into account
|
||||
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
|
||||
is so judged Affirmer hereby grants to each affected person a royalty-free,
|
||||
non transferable, non sublicensable, non exclusive, irrevocable and
|
||||
unconditional license to exercise Affirmer's Copyright and Related Rights in
|
||||
the Work (i) in all territories worldwide, (ii) for the maximum duration
|
||||
provided by applicable law or treaty (including future time extensions), (iii)
|
||||
in any current or future medium and for any number of copies, and (iv) for any
|
||||
purpose whatsoever, including without limitation commercial, advertising or
|
||||
promotional purposes (the "License"). The License shall be deemed effective as
|
||||
of the date CC0 was applied by Affirmer to the Work. Should any part of the
|
||||
License for any reason be judged legally invalid or ineffective under
|
||||
applicable law, such partial invalidity or ineffectiveness shall not
|
||||
invalidate the remainder of the License, and in such case Affirmer hereby
|
||||
affirms that he or she will not (i) exercise any of his or her remaining
|
||||
Copyright and Related Rights in the Work or (ii) assert any associated claims
|
||||
and causes of action with respect to the Work, in either case contrary to
|
||||
Affirmer's express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
|
||||
b. Affirmer offers the Work as-is and makes no representations or warranties
|
||||
of any kind concerning the Work, express, implied, statutory or otherwise,
|
||||
including without limitation warranties of title, merchantability, fitness
|
||||
for a particular purpose, non infringement, or the absence of latent or
|
||||
other defects, accuracy, or the present or absence of errors, whether or not
|
||||
discoverable, all to the greatest extent permissible under applicable law.
|
||||
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without limitation
|
||||
any person's Copyright and Related Rights in the Work. Further, Affirmer
|
||||
disclaims responsibility for obtaining any necessary consents, permissions
|
||||
or other rights required for any use of the Work.
|
||||
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to this
|
||||
CC0 or use of the Work.
|
||||
|
||||
For more information, please see
|
||||
<http://creativecommons.org/publicdomain/zero/1.0/>
|
11
hw/application_fpga/fw/mta1_mkdf/blake2s/README.md
Normal file
11
hw/application_fpga/fw/mta1_mkdf/blake2s/README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# blake2s
|
||||
|
||||
A Blake2s implementation taken from Joachim Strömbergson's
|
||||
|
||||
https://github.com/secworks/blake2s
|
||||
|
||||
Specifically from
|
||||
|
||||
https://github.com/secworks/blake2s/tree/master/src/model
|
||||
|
||||
Minor local changes for build purposes.
|
352
hw/application_fpga/fw/mta1_mkdf/blake2s/blake2s.c
Normal file
352
hw/application_fpga/fw/mta1_mkdf/blake2s/blake2s.c
Normal file
|
@ -0,0 +1,352 @@
|
|||
//======================================================================
|
||||
//
|
||||
// blake2s.c
|
||||
// ---------
|
||||
//
|
||||
// A simple blake2s Reference Implementation.
|
||||
//======================================================================
|
||||
|
||||
#include "../types.h"
|
||||
#include "../lib.h"
|
||||
#include "blake2s.h"
|
||||
|
||||
// Dummy printf() for verbose mode
|
||||
static void printf(const char *format, ...)
|
||||
{
|
||||
}
|
||||
|
||||
#define VERBOSE 0
|
||||
#define SHOW_V 0
|
||||
#define SHOW_M_WORDS 0
|
||||
|
||||
|
||||
// Cyclic right rotation.
|
||||
#ifndef ROTR32
|
||||
#define ROTR32(x, y) (((x) >> (y)) ^ ((x) << (32 - (y))))
|
||||
#endif
|
||||
|
||||
|
||||
// Little-endian byte access.
|
||||
#define B2S_GET32(p) \
|
||||
(((uint32_t) ((uint8_t *) (p))[0]) ^ \
|
||||
(((uint32_t) ((uint8_t *) (p))[1]) << 8) ^ \
|
||||
(((uint32_t) ((uint8_t *) (p))[2]) << 16) ^ \
|
||||
(((uint32_t) ((uint8_t *) (p))[3]) << 24))
|
||||
|
||||
|
||||
// Initialization Vector.
|
||||
static const uint32_t blake2s_iv[8] = {
|
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
void print_v(uint32_t *v) {
|
||||
printf("0x%08x, 0x%08x, 0x%08x, 0x%08x\n", v[0], v[1], v[2], v[3]);
|
||||
printf("0x%08x, 0x%08x, 0x%08x, 0x%08x\n", v[4], v[5], v[6], v[7]);
|
||||
printf("0x%08x, 0x%08x, 0x%08x, 0x%08x\n", v[8], v[9], v[10], v[11]);
|
||||
printf("0x%08x, 0x%08x, 0x%08x, 0x%08x\n", v[12], v[13], v[14], v[15]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// print_ctx()
|
||||
// Print the contents of the context data structure.
|
||||
//------------------------------------------------------------------
|
||||
void print_ctx(blake2s_ctx *ctx) {
|
||||
printf("Chained state (h):\n");
|
||||
printf("0x%08x, 0x%08x, 0x%08x, 0x%08x, ",
|
||||
ctx->h[0], ctx->h[1], ctx->h[2], ctx->h[3]);
|
||||
printf("0x%08x, 0x%08x, 0x%08x, 0x%08x",
|
||||
ctx->h[4], ctx->h[5], ctx->h[6], ctx->h[7]);
|
||||
printf("\n");
|
||||
|
||||
printf("Byte counter (t):\n");
|
||||
printf("0x%08x, 0x%08x", ctx->t[0], ctx->t[1]);
|
||||
printf("\n");
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// B2S_G macro redefined as a G function.
|
||||
// Allows us to output intermediate values for debugging.
|
||||
//------------------------------------------------------------------
|
||||
void G(uint32_t *v, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t y) {
|
||||
if (VERBOSE) {
|
||||
printf("G started.\n");
|
||||
}
|
||||
|
||||
if (SHOW_V) {
|
||||
printf("v before processing:\n");
|
||||
print_v(&v[0]);
|
||||
}
|
||||
|
||||
if (SHOW_M_WORDS) {
|
||||
printf("x: 0x%08x, y: 0x%08x\n", x, y);
|
||||
}
|
||||
|
||||
v[a] = v[a] + v[b] + x;
|
||||
v[d] = ROTR32(v[d] ^ v[a], 16);
|
||||
v[c] = v[c] + v[d];
|
||||
v[b] = ROTR32(v[b] ^ v[c], 12);
|
||||
v[a] = v[a] + v[b] + y;
|
||||
v[d] = ROTR32(v[d] ^ v[a], 8);
|
||||
v[c] = v[c] + v[d];
|
||||
v[b] = ROTR32(v[b] ^ v[c], 7);
|
||||
|
||||
if (SHOW_V) {
|
||||
printf("v after processing:\n");
|
||||
print_v(&v[0]);
|
||||
}
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("G completed.\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Compression function. "last" flag indicates last block.
|
||||
//------------------------------------------------------------------
|
||||
static void blake2s_compress(blake2s_ctx *ctx, int last)
|
||||
{
|
||||
const uint8_t sigma[10][16] = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
|
||||
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
|
||||
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
|
||||
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
|
||||
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
|
||||
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
|
||||
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
|
||||
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}
|
||||
};
|
||||
|
||||
int i;
|
||||
uint32_t v[16], m[16];
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("blake2s_compress started.\n");
|
||||
}
|
||||
|
||||
// init work variables
|
||||
for (i = 0; i < 8; i++) {
|
||||
v[i] = ctx->h[i];
|
||||
v[i + 8] = blake2s_iv[i];
|
||||
}
|
||||
|
||||
// low 32 bits of offset
|
||||
// high 32 bits
|
||||
if (VERBOSE) {
|
||||
printf("t[0]: 0x%08x, t[1]: 0x%08x\n", ctx->t[0], ctx->t[1]);
|
||||
}
|
||||
v[12] ^= ctx->t[0];
|
||||
v[13] ^= ctx->t[1];
|
||||
|
||||
// last block flag set ?
|
||||
if (last) {
|
||||
v[14] = ~v[14];
|
||||
}
|
||||
|
||||
// get little-endian words
|
||||
for (i = 0; i < 16; i++) {
|
||||
m[i] = B2S_GET32(&ctx->b[4 * i]);
|
||||
}
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("v before G processing:\n");
|
||||
print_v(&v[0]);
|
||||
}
|
||||
|
||||
// Ten rounds of the G function applied on rows, diagonal.
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (VERBOSE) {
|
||||
printf("Round %02d:\n", (i + 1));
|
||||
printf("Row processing started.\n");
|
||||
}
|
||||
|
||||
G(&v[0], 0, 4, 8, 12, m[sigma[i][ 0]], m[sigma[i][ 1]]);
|
||||
G(&v[0], 1, 5, 9, 13, m[sigma[i][ 2]], m[sigma[i][ 3]]);
|
||||
G(&v[0], 2, 6, 10, 14, m[sigma[i][ 4]], m[sigma[i][ 5]]);
|
||||
G(&v[0], 3, 7, 11, 15, m[sigma[i][ 6]], m[sigma[i][ 7]]);
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("Row processing completed.\n");
|
||||
printf("Diagonal processing started.\n");
|
||||
}
|
||||
|
||||
G(&v[0], 0, 5, 10, 15, m[sigma[i][ 8]], m[sigma[i][ 9]]);
|
||||
G(&v[0], 1, 6, 11, 12, m[sigma[i][10]], m[sigma[i][11]]);
|
||||
G(&v[0], 2, 7, 8, 13, m[sigma[i][12]], m[sigma[i][13]]);
|
||||
G(&v[0], 3, 4, 9, 14, m[sigma[i][14]], m[sigma[i][15]]);
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("Diagonal processing completed.\n");
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("v after G processing:\n");
|
||||
print_v(&v[0]);
|
||||
}
|
||||
|
||||
// Update the hash state.
|
||||
for (i = 0; i < 8; ++i) {
|
||||
ctx->h[i] ^= v[i] ^ v[i + 8];
|
||||
}
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("blake2s_compress completed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Initialize the hashing context "ctx" with optional key "key".
|
||||
// 1 <= outlen <= 32 gives the digest size in bytes.
|
||||
// Secret key (also <= 32 bytes) is optional (keylen = 0).
|
||||
//------------------------------------------------------------------
|
||||
int blake2s_init(blake2s_ctx *ctx, size_t outlen,
|
||||
const void *key, size_t keylen) // (keylen=0: no key)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("blake2s_init started.\n");
|
||||
printf("Context before blake2s_init processing:\n");
|
||||
print_ctx(ctx);
|
||||
}
|
||||
|
||||
if (outlen == 0 || outlen > 32 || keylen > 32)
|
||||
return -1; // illegal parameters
|
||||
|
||||
for (i = 0; i < 8; i++) // state, "param block"
|
||||
ctx->h[i] = blake2s_iv[i];
|
||||
ctx->h[0] ^= 0x01010000 ^ (keylen << 8) ^ outlen;
|
||||
|
||||
ctx->t[0] = 0; // input count low word
|
||||
ctx->t[1] = 0; // input count high word
|
||||
ctx->c = 0; // pointer within buffer
|
||||
ctx->outlen = outlen;
|
||||
|
||||
for (i = keylen; i < 64; i++) // zero input block
|
||||
ctx->b[i] = 0;
|
||||
if (keylen > 0) {
|
||||
blake2s_update(ctx, key, keylen);
|
||||
ctx->c = 64; // at the end
|
||||
}
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("Context after blake2s_init processing:\n");
|
||||
print_ctx(ctx);
|
||||
printf("blake2s_init completed.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Add "inlen" bytes from "in" into the hash.
|
||||
//------------------------------------------------------------------
|
||||
void blake2s_update(blake2s_ctx *ctx,
|
||||
const void *in, size_t inlen) // data bytes
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("blake2s_update started.\n");
|
||||
printf("Context before blake2s_update processing:\n");
|
||||
print_ctx(ctx);
|
||||
}
|
||||
|
||||
for (i = 0; i < inlen; i++) {
|
||||
if (ctx->c == 64) { // buffer full ?
|
||||
ctx->t[0] += ctx->c; // add counters
|
||||
if (ctx->t[0] < ctx->c) // carry overflow ?
|
||||
ctx->t[1]++; // high word
|
||||
blake2s_compress(ctx, 0); // compress (not last)
|
||||
ctx->c = 0; // counter to zero
|
||||
}
|
||||
ctx->b[ctx->c++] = ((const uint8_t *) in)[i];
|
||||
}
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("Context after blake2s_update processing:\n");
|
||||
print_ctx(ctx);
|
||||
printf("blake2s_update completed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Generate the message digest (size given in init).
|
||||
// Result placed in "out".
|
||||
//------------------------------------------------------------------
|
||||
void blake2s_final(blake2s_ctx *ctx, void *out)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("blake2s_final started.\n");
|
||||
printf("Context before blake2s_final processing:\n");
|
||||
print_ctx(ctx);
|
||||
}
|
||||
|
||||
ctx->t[0] += ctx->c; // mark last block offset
|
||||
|
||||
// carry overflow
|
||||
// high word
|
||||
if (ctx->t[0] < ctx->c) {
|
||||
ctx->t[1]++;
|
||||
}
|
||||
|
||||
// fill up with zeros
|
||||
// final block flag = 1
|
||||
while (ctx->c < 64) {
|
||||
ctx->b[ctx->c++] = 0;
|
||||
}
|
||||
blake2s_compress(ctx, 1);
|
||||
|
||||
// little endian convert and store
|
||||
for (i = 0; i < ctx->outlen; i++) {
|
||||
((uint8_t *) out)[i] =
|
||||
(ctx->h[i >> 2] >> (8 * (i & 3))) & 0xFF;
|
||||
}
|
||||
|
||||
if (VERBOSE) {
|
||||
printf("Context after blake2s_final processing:\n");
|
||||
print_ctx(ctx);
|
||||
printf("blake2s_final completed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Convenience function for all-in-one computation.
|
||||
//------------------------------------------------------------------
|
||||
int blake2s(void *out, size_t outlen,
|
||||
const void *key, size_t keylen,
|
||||
const void *in, size_t inlen)
|
||||
{
|
||||
blake2s_ctx ctx;
|
||||
|
||||
if (blake2s_init(&ctx, outlen, key, keylen))
|
||||
return -1;
|
||||
|
||||
blake2s_update(&ctx, in, inlen);
|
||||
|
||||
blake2s_final(&ctx, out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
38
hw/application_fpga/fw/mta1_mkdf/blake2s/blake2s.h
Normal file
38
hw/application_fpga/fw/mta1_mkdf/blake2s/blake2s.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
// blake2s.h
|
||||
// BLAKE2s Hashing Context and API Prototypes
|
||||
|
||||
#ifndef BLAKE2S_H
|
||||
#define BLAKE2S_H
|
||||
|
||||
#include "../types.h"
|
||||
|
||||
// state context
|
||||
typedef struct {
|
||||
uint8_t b[64]; // input buffer
|
||||
uint32_t h[8]; // chained state
|
||||
uint32_t t[2]; // total number of bytes
|
||||
size_t c; // pointer for b[]
|
||||
size_t outlen; // digest size
|
||||
} blake2s_ctx;
|
||||
|
||||
// Initialize the hashing context "ctx" with optional key "key".
|
||||
// 1 <= outlen <= 32 gives the digest size in bytes.
|
||||
// Secret key (also <= 32 bytes) is optional (keylen = 0).
|
||||
int blake2s_init(blake2s_ctx *ctx, size_t outlen,
|
||||
const void *key, size_t keylen); // secret key
|
||||
|
||||
// Add "inlen" bytes from "in" into the hash.
|
||||
void blake2s_update(blake2s_ctx *ctx, // context
|
||||
const void *in, size_t inlen); // data to be hashed
|
||||
|
||||
// Generate the message digest (size given in init).
|
||||
// Result placed in "out".
|
||||
void blake2s_final(blake2s_ctx *ctx, void *out);
|
||||
|
||||
// All-in-one convenience function.
|
||||
int blake2s(void *out, size_t outlen, // return buffer for digest
|
||||
const void *key, size_t keylen, // optional secret key
|
||||
const void *in, size_t inlen); // data to be hashed
|
||||
|
||||
#endif
|
||||
|
71
hw/application_fpga/fw/mta1_mkdf/firmware.lds
Normal file
71
hw/application_fpga/fw/mta1_mkdf/firmware.lds
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* TODO ROM size should be adjusted, RAM should be ok. */
|
||||
ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x20000 /* 128 KB */
|
||||
RAM (rwx) : ORIGIN = 0x40000000, LENGTH = 0x20000 /* 128 KB */
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text.init :
|
||||
{
|
||||
*(.text.init)
|
||||
} >ROM
|
||||
|
||||
.htif :
|
||||
{
|
||||
. = ALIGN(0x00000000);
|
||||
*(.htif)
|
||||
} >ROM
|
||||
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
*(.srodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.srodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
_sidata = _etext;
|
||||
} >ROM
|
||||
|
||||
.data : AT (_etext)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
. = ALIGN(4);
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
*(.sdata) /* .sdata sections */
|
||||
*(.sdata*) /* .sdata* sections */
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} >RAM
|
||||
|
||||
/* Uninitialized data section */
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(.sbss)
|
||||
*(.sbss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
} >RAM
|
||||
/* Init stack to _ebss + size */
|
||||
}
|
171
hw/application_fpga/fw/mta1_mkdf/lib.c
Normal file
171
hw/application_fpga/fw/mta1_mkdf/lib.c
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "types.h"
|
||||
|
||||
#if NOCONSOLE
|
||||
void putc(int ch)
|
||||
{
|
||||
}
|
||||
|
||||
void lf()
|
||||
{
|
||||
}
|
||||
|
||||
void puthex(uint8_t c)
|
||||
{
|
||||
}
|
||||
|
||||
void putinthex(const uint32_t n)
|
||||
{
|
||||
}
|
||||
|
||||
int puts(const char *s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hexdump(uint8_t *buf, int len)
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
struct {
|
||||
uint32_t arr[2];
|
||||
} volatile tohost __attribute__((section(".htif")));
|
||||
struct {
|
||||
uint32_t arr[2];
|
||||
} volatile fromhost __attribute__((section(".htif")));
|
||||
|
||||
static void htif_send(uint8_t dev, uint8_t cmd, int64_t data)
|
||||
{
|
||||
/* endian neutral encoding with ordered 32-bit writes */
|
||||
union {
|
||||
uint32_t arr[2];
|
||||
uint64_t val;
|
||||
} encode = {.val = (uint64_t)dev << 56 | (uint64_t)cmd << 48 | data};
|
||||
tohost.arr[0] = encode.arr[0];
|
||||
tohost.arr[1] = encode.arr[1];
|
||||
}
|
||||
|
||||
static void htif_set_tohost(uint8_t dev, uint8_t cmd, int64_t data)
|
||||
{
|
||||
/* send data with specified device and command */
|
||||
while (tohost.arr[0]) {
|
||||
asm volatile("" : : "r"(fromhost.arr[0]));
|
||||
asm volatile("" : : "r"(fromhost.arr[1]));
|
||||
}
|
||||
htif_send(dev, cmd, data);
|
||||
}
|
||||
|
||||
static int htif_putchar(int ch)
|
||||
{
|
||||
htif_set_tohost(1, 1, ch & 0xff);
|
||||
return ch & 0xff;
|
||||
}
|
||||
|
||||
int puts(const char *s)
|
||||
{
|
||||
while (*s)
|
||||
htif_putchar(*s++);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hexdump(uint8_t *buf, int len)
|
||||
{
|
||||
uint8_t *row;
|
||||
uint8_t *byte;
|
||||
uint8_t *max;
|
||||
|
||||
row = buf;
|
||||
max = &buf[len];
|
||||
for (byte = 0; byte != max; row = byte) {
|
||||
for (byte = row; byte != max && byte != (row + 16); byte++) {
|
||||
puthex(*byte);
|
||||
}
|
||||
|
||||
lf();
|
||||
}
|
||||
}
|
||||
|
||||
void putc(int ch)
|
||||
{
|
||||
htif_putchar(ch);
|
||||
}
|
||||
|
||||
void lf()
|
||||
{
|
||||
htif_putchar('\n');
|
||||
}
|
||||
|
||||
void puthex(uint8_t c)
|
||||
{
|
||||
unsigned int upper = (c >> 4) & 0xf;
|
||||
unsigned int lower = c & 0xf;
|
||||
|
||||
htif_putchar(upper < 10 ? '0' + upper : 'a' - 10 + upper);
|
||||
htif_putchar(lower < 10 ? '0' + lower : 'a' - 10 + lower);
|
||||
}
|
||||
|
||||
void putinthex(const uint32_t n)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
|
||||
memcpy(buf, &n, 4);
|
||||
puts("0x");
|
||||
for (int i = 3; i > -1; i--) {
|
||||
puthex(buf[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *memset(void *dest, int c, unsigned n)
|
||||
{
|
||||
uint8_t *s = dest;
|
||||
|
||||
for (; n; n--, s++)
|
||||
*s = c;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
__attribute__((used)) void *memcpy(void *dest, const void *src, unsigned n)
|
||||
{
|
||||
uint8_t *src_byte = (uint8_t *)src;
|
||||
uint8_t *dest_byte = (uint8_t *)dest;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
dest_byte[i] = src_byte[i];
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
__attribute__((used)) void *wordcpy(void *dest, const void *src, unsigned n)
|
||||
{
|
||||
uint32_t *src_word = (uint32_t *)src;
|
||||
uint32_t *dest_word = (uint32_t *)dest;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
dest_word[i] = src_word[i];
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memeq(void *dest, const void *src, unsigned n)
|
||||
{
|
||||
uint8_t *src_byte = (uint8_t *)src;
|
||||
uint8_t *dest_byte = (uint8_t *)dest;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (dest_byte[i] != src_byte[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
22
hw/application_fpga/fw/mta1_mkdf/lib.h
Normal file
22
hw/application_fpga/fw/mta1_mkdf/lib.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#ifndef LIB_H
|
||||
#define LIB_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void putc(int ch);
|
||||
void lf();
|
||||
void puthex(uint8_t c);
|
||||
void putinthex(const uint32_t n);
|
||||
int puts(const char *s);
|
||||
void hexdump(uint8_t *buf, int len);
|
||||
void *memset(void *dest, int c, unsigned n);
|
||||
void *memcpy(void *dest, const void *src, unsigned n);
|
||||
void *wordcpy(void *dest, const void *src, unsigned n);
|
||||
int memeq(void *dest, const void *src, unsigned n);
|
||||
|
||||
#endif
|
262
hw/application_fpga/fw/mta1_mkdf/main.c
Normal file
262
hw/application_fpga/fw/mta1_mkdf/main.c
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "../mta1_mkdf_mem.h"
|
||||
#include "blake2s/blake2s.h"
|
||||
#include "lib.h"
|
||||
#include "proto.h"
|
||||
#include "types.h"
|
||||
|
||||
// In RAM + above the stack (0x40010000)
|
||||
#define APP_RAM_ADDR (MTA1_MKDF_RAM_BASE + 0x10000)
|
||||
#define APP_MAX_SIZE 65536
|
||||
|
||||
// clang-format off
|
||||
static volatile uint32_t *uds = (volatile uint32_t *)MTA1_MKDF_MMIO_UDS_FIRST;
|
||||
static volatile uint32_t *switch_app = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_SWITCH_APP;
|
||||
static volatile uint32_t *name0 = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_NAME0;
|
||||
static volatile uint32_t *name1 = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_NAME1;
|
||||
static volatile uint32_t *ver = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_VERSION;
|
||||
static volatile uint32_t *cdi = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_CDI_FIRST;
|
||||
static volatile uint32_t *app_addr = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_APP_ADDR;
|
||||
static volatile uint32_t *app_size = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_APP_SIZE;
|
||||
|
||||
#define LED_RED (1 << MTA1_MKDF_MMIO_MTA1_LED_R_BIT)
|
||||
#define LED_GREEN (1 << MTA1_MKDF_MMIO_MTA1_LED_G_BIT)
|
||||
#define LED_BLUE (1 << MTA1_MKDF_MMIO_MTA1_LED_B_BIT)
|
||||
|
||||
static void print_hw_version(uint32_t name0, uint32_t name1, uint32_t ver)
|
||||
{
|
||||
puts("Hello, I'm ");
|
||||
putc(name0 >> 24);
|
||||
putc(name0 >> 16);
|
||||
putc(name0 >> 8);
|
||||
putc(name0);
|
||||
|
||||
putc('-');
|
||||
|
||||
putc(name1 >> 24);
|
||||
putc(name1 >> 16);
|
||||
putc(name1 >> 8);
|
||||
putc(name1);
|
||||
|
||||
putc(' ');
|
||||
putinthex(ver);
|
||||
lf();
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
static void print_digest(uint8_t *md)
|
||||
{
|
||||
puts("The app digest:\n");
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
puthex(md[i + 8 * j]);
|
||||
}
|
||||
lf();
|
||||
}
|
||||
lf();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
uint32_t local_name0 = *name0;
|
||||
uint32_t local_name1 = *name1;
|
||||
uint32_t local_ver = *ver;
|
||||
struct frame_header hdr; // Used in both directions
|
||||
uint8_t cmd[CMDLEN_MAXBYTES];
|
||||
uint8_t rsp[CMDLEN_MAXBYTES];
|
||||
uint8_t *loadaddr = (uint8_t *)APP_RAM_ADDR;
|
||||
int left = 0; // Bytes left to read
|
||||
int nbytes = 0; // Bytes to write to memory
|
||||
uint32_t local_app_size = 0;
|
||||
uint8_t in;
|
||||
uint8_t digest[32];
|
||||
|
||||
print_hw_version(local_name0, local_name1, local_ver);
|
||||
|
||||
for (;;) {
|
||||
// blocking; fw flashing white while waiting for cmd
|
||||
in = readbyte_ledflash(LED_RED | LED_BLUE | LED_GREEN, 500000);
|
||||
|
||||
if (parseframe(in, &hdr) == -1) {
|
||||
puts("Couldn't parse header\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(cmd, 0, CMDLEN_MAXBYTES);
|
||||
// Read firmware command: Blocks!
|
||||
read(cmd, hdr.len);
|
||||
|
||||
// Is it for us?
|
||||
if (hdr.endpoint != DST_FW) {
|
||||
puts("Message not meant for us\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reset response buffer
|
||||
memset(rsp, 0, CMDLEN_MAXBYTES);
|
||||
|
||||
// Min length is 1 byte so this should always be here
|
||||
switch (cmd[0]) {
|
||||
case FW_CMD_NAME_VERSION:
|
||||
puts("request: name-version\n");
|
||||
|
||||
if (hdr.len != 1) {
|
||||
// Bad length - give them an empty response
|
||||
fwreply(hdr, FW_RSP_NAME_VERSION, rsp);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(rsp, (uint8_t *)&local_name0, 4);
|
||||
memcpy(rsp + 4, (uint8_t *)&local_name1, 4);
|
||||
memcpy(rsp + 8, (uint8_t *)&local_ver, 4);
|
||||
|
||||
fwreply(hdr, FW_RSP_NAME_VERSION, rsp);
|
||||
break;
|
||||
|
||||
case FW_CMD_LOAD_APP_SIZE:
|
||||
puts("request: load-app-size\n");
|
||||
|
||||
if (hdr.len != 32) {
|
||||
// Bad length
|
||||
rsp[0] = STATUS_BAD;
|
||||
fwreply(hdr, FW_RSP_LOAD_APP_SIZE, rsp);
|
||||
break;
|
||||
}
|
||||
|
||||
// cmd[1..4] contains the size.
|
||||
local_app_size = cmd[1] + (cmd[2] << 8) +
|
||||
(cmd[3] << 16) + (cmd[4] << 24);
|
||||
|
||||
puts("app size: ");
|
||||
putinthex(local_app_size);
|
||||
lf();
|
||||
|
||||
if (local_app_size > APP_MAX_SIZE) {
|
||||
rsp[0] = STATUS_BAD;
|
||||
fwreply(hdr, FW_RSP_LOAD_APP_SIZE, rsp);
|
||||
break;
|
||||
}
|
||||
|
||||
*app_size = local_app_size;
|
||||
*app_addr = 0;
|
||||
|
||||
// Reset where to start loading the program
|
||||
loadaddr = (uint8_t *)APP_RAM_ADDR;
|
||||
left = *app_size;
|
||||
|
||||
rsp[0] = STATUS_OK;
|
||||
fwreply(hdr, FW_RSP_LOAD_APP_SIZE, rsp);
|
||||
break;
|
||||
|
||||
case FW_CMD_LOAD_APP_DATA:
|
||||
puts("request: load-app-data\n");
|
||||
|
||||
if (hdr.len != 128 || *app_size == 0) {
|
||||
// Bad length of this command or bad app size -
|
||||
// they need to call FW_CMD_LOAD_APP_SIZE first
|
||||
rsp[0] = STATUS_BAD;
|
||||
fwreply(hdr, FW_RSP_LOAD_APP_DATA, rsp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (left > 127) {
|
||||
nbytes = 127;
|
||||
} else {
|
||||
nbytes = left;
|
||||
}
|
||||
memcpy(loadaddr, cmd + 1, nbytes);
|
||||
loadaddr += nbytes;
|
||||
left -= nbytes;
|
||||
|
||||
if (left == 0) {
|
||||
uint8_t scratch[64];
|
||||
|
||||
puts("Fully loaded ");
|
||||
putinthex(*app_size);
|
||||
lf();
|
||||
|
||||
*app_addr = APP_RAM_ADDR;
|
||||
// Get the Blake2S digest of the app - store it
|
||||
// for later queries
|
||||
blake2s(digest, 32, NULL, 0,
|
||||
(const void *)*app_addr, *app_size);
|
||||
print_digest(digest);
|
||||
|
||||
// CDI = hash(uds, hash(app))
|
||||
uint32_t local_cdi[8];
|
||||
|
||||
// Only word aligned access to UDS
|
||||
wordcpy(scratch, (void *)uds, 8);
|
||||
memcpy(scratch + 32, digest, 32);
|
||||
blake2s((void *)local_cdi, 32, NULL, 0,
|
||||
(const void *)scratch, 64);
|
||||
// Only word aligned access to CDI
|
||||
wordcpy((void *)cdi, (void *)local_cdi, 8);
|
||||
}
|
||||
|
||||
rsp[0] = STATUS_OK;
|
||||
fwreply(hdr, FW_RSP_LOAD_APP_DATA, rsp);
|
||||
break;
|
||||
|
||||
case FW_CMD_RUN_APP:
|
||||
puts("request: run-app\n");
|
||||
|
||||
if (hdr.len != 1) {
|
||||
// Bad length
|
||||
rsp[0] = STATUS_BAD;
|
||||
fwreply(hdr, FW_RSP_RUN_APP, rsp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (*app_size > 0 && *app_addr != 0) {
|
||||
rsp[0] = STATUS_OK;
|
||||
fwreply(hdr, FW_RSP_RUN_APP, rsp);
|
||||
|
||||
// Flip over to application mode
|
||||
*switch_app = 1;
|
||||
|
||||
// Jump to app - doesn't return
|
||||
// First clears memory of firmware remains
|
||||
puts("Jumping to ");
|
||||
putinthex(*app_addr);
|
||||
lf();
|
||||
// clang-format off
|
||||
asm volatile(
|
||||
"li a0, 0x40000000;" // MTA1_MKDF_RAM_BASE
|
||||
"li a1, 0x40010000;"
|
||||
"loop:;"
|
||||
"sw zero, 0(a0);"
|
||||
"addi a0, a0, 4;"
|
||||
"blt a0, a1, loop;"
|
||||
// Get value at MTA1_MKDF_MMIO_MTA1_APP_ADDR
|
||||
"lui a0,0xff000;"
|
||||
"lw a0,0x030(a0);"
|
||||
"jalr x0,0(a0);"
|
||||
::: "memory");
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
rsp[0] = STATUS_BAD;
|
||||
fwreply(hdr, FW_RSP_RUN_APP, rsp);
|
||||
break;
|
||||
|
||||
case FW_CMD_GET_APP_DIGEST:
|
||||
puts("request: get-app-digest\n");
|
||||
|
||||
memcpy(rsp, &digest, 32);
|
||||
fwreply(hdr, FW_RSP_GET_APP_DIGEST, rsp);
|
||||
break;
|
||||
|
||||
default:
|
||||
puts("Received unknown firmware command: 0x");
|
||||
puthex(cmd[0]);
|
||||
lf();
|
||||
}
|
||||
}
|
||||
|
||||
return (int)0xcafebabe;
|
||||
}
|
156
hw/application_fpga/fw/mta1_mkdf/proto.c
Normal file
156
hw/application_fpga/fw/mta1_mkdf/proto.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "proto.h"
|
||||
#include "../mta1_mkdf_mem.h"
|
||||
#include "lib.h"
|
||||
#include "types.h"
|
||||
|
||||
// clang-format off
|
||||
static volatile uint32_t *can_rx = (volatile uint32_t *)MTA1_MKDF_MMIO_UART_RX_STATUS;
|
||||
static volatile uint32_t *rx = (volatile uint32_t *)MTA1_MKDF_MMIO_UART_RX_DATA;
|
||||
static volatile uint32_t *can_tx = (volatile uint32_t *)MTA1_MKDF_MMIO_UART_TX_STATUS;
|
||||
static volatile uint32_t *tx = (volatile uint32_t *)MTA1_MKDF_MMIO_UART_TX_DATA;
|
||||
static volatile uint32_t *led = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_LED;
|
||||
// clang-format on
|
||||
|
||||
uint8_t genhdr(uint8_t id, uint8_t endpoint, uint8_t status, enum cmdlen len)
|
||||
{
|
||||
return (id << 5) | (endpoint << 3) | (status << 2) | len;
|
||||
}
|
||||
|
||||
int parseframe(uint8_t b, struct frame_header *hdr)
|
||||
{
|
||||
if ((b & 0x80) != 0) {
|
||||
// Bad version
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((b & 0x4) != 0) {
|
||||
// Must be 0
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdr->id = (b & 0x60) >> 5;
|
||||
hdr->endpoint = (b & 0x18) >> 3;
|
||||
|
||||
// Length
|
||||
switch (b & 0x3) {
|
||||
case LEN_1:
|
||||
hdr->len = 1;
|
||||
break;
|
||||
case LEN_4:
|
||||
hdr->len = 4;
|
||||
break;
|
||||
case LEN_32:
|
||||
hdr->len = 32;
|
||||
break;
|
||||
case LEN_128:
|
||||
hdr->len = 128;
|
||||
break;
|
||||
default:
|
||||
// Unknown length
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send a firmware reply with a frame header, response code rspcode and
|
||||
// following data in buf
|
||||
void fwreply(struct frame_header hdr, enum fwcmd rspcode, uint8_t *buf)
|
||||
{
|
||||
size_t nbytes;
|
||||
enum cmdlen len; // length covering (rspcode + length of buf)
|
||||
|
||||
switch (rspcode) {
|
||||
case FW_RSP_NAME_VERSION:
|
||||
len = LEN_32;
|
||||
nbytes = 32;
|
||||
break;
|
||||
|
||||
case FW_RSP_LOAD_APP_SIZE:
|
||||
len = LEN_4;
|
||||
nbytes = 4;
|
||||
break;
|
||||
|
||||
case FW_RSP_LOAD_APP_DATA:
|
||||
len = LEN_4;
|
||||
nbytes = 4;
|
||||
break;
|
||||
|
||||
case FW_RSP_RUN_APP:
|
||||
len = LEN_4;
|
||||
nbytes = 4;
|
||||
break;
|
||||
|
||||
case FW_RSP_GET_APP_DIGEST:
|
||||
len = LEN_128;
|
||||
nbytes = 128;
|
||||
break;
|
||||
|
||||
default:
|
||||
puts("fwreply(): Unknown response code: 0x");
|
||||
puthex(rspcode);
|
||||
lf();
|
||||
return;
|
||||
}
|
||||
|
||||
// Frame Protocol Header
|
||||
writebyte(genhdr(hdr.id, hdr.endpoint, 0x0, len));
|
||||
|
||||
// FW protocol header
|
||||
writebyte(rspcode);
|
||||
nbytes--;
|
||||
|
||||
write(buf, nbytes);
|
||||
}
|
||||
|
||||
void writebyte(uint8_t b)
|
||||
{
|
||||
for (;;) {
|
||||
if (*can_tx) {
|
||||
*tx = b;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write(uint8_t *buf, size_t nbytes)
|
||||
{
|
||||
for (int i = 0; i < nbytes; i++) {
|
||||
writebyte(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t readbyte()
|
||||
{
|
||||
for (;;) {
|
||||
if (*can_rx) {
|
||||
return *rx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t readbyte_ledflash(int ledvalue, int loopcount)
|
||||
{
|
||||
int led_on = 0;
|
||||
for (;;) {
|
||||
*led = led_on ? ledvalue : 0;
|
||||
for (int i = 0; i < loopcount; i++) {
|
||||
if (*can_rx) {
|
||||
return *rx;
|
||||
}
|
||||
}
|
||||
led_on = !led_on;
|
||||
}
|
||||
}
|
||||
|
||||
void read(uint8_t *buf, size_t nbytes)
|
||||
{
|
||||
for (int n = 0; n < nbytes; n++) {
|
||||
buf[n] = readbyte();
|
||||
}
|
||||
}
|
62
hw/application_fpga/fw/mta1_mkdf/proto.h
Normal file
62
hw/application_fpga/fw/mta1_mkdf/proto.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifndef PROTO_H
|
||||
#define PROTO_H
|
||||
|
||||
enum endpoints {
|
||||
DST_HW_IFPGA,
|
||||
DST_HW_AFPGA,
|
||||
DST_FW,
|
||||
DST_SW
|
||||
};
|
||||
|
||||
enum cmdlen {
|
||||
LEN_1,
|
||||
LEN_4,
|
||||
LEN_32,
|
||||
LEN_128
|
||||
};
|
||||
|
||||
#define CMDLEN_MAXBYTES 128
|
||||
|
||||
// clang-format off
|
||||
enum fwcmd {
|
||||
FW_CMD_NAME_VERSION = 0x01,
|
||||
FW_RSP_NAME_VERSION = 0x02,
|
||||
FW_CMD_LOAD_APP_SIZE = 0x03,
|
||||
FW_RSP_LOAD_APP_SIZE = 0x04,
|
||||
FW_CMD_LOAD_APP_DATA = 0x05,
|
||||
FW_RSP_LOAD_APP_DATA = 0x06,
|
||||
FW_CMD_RUN_APP = 0x07,
|
||||
FW_RSP_RUN_APP = 0x08,
|
||||
FW_CMD_GET_APP_DIGEST = 0x09,
|
||||
FW_RSP_GET_APP_DIGEST = 0x10
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
enum status {
|
||||
STATUS_OK,
|
||||
STATUS_BAD
|
||||
};
|
||||
|
||||
struct frame_header {
|
||||
uint8_t id;
|
||||
enum endpoints endpoint;
|
||||
enum cmdlen len;
|
||||
};
|
||||
|
||||
uint8_t genhdr(uint8_t id, uint8_t endpoint, uint8_t status, enum cmdlen len);
|
||||
int parseframe(uint8_t b, struct frame_header *hdr);
|
||||
void fwreply(struct frame_header hdr, enum fwcmd rspcode, uint8_t *buf);
|
||||
void writebyte(uint8_t b);
|
||||
void write(uint8_t *buf, size_t nbytes);
|
||||
uint8_t readbyte();
|
||||
uint8_t readbyte_ledflash(int ledvalue, int loopcount);
|
||||
void read(uint8_t *buf, size_t nbytes);
|
||||
|
||||
#endif
|
72
hw/application_fpga/fw/mta1_mkdf/start.S
Normal file
72
hw/application_fpga/fw/mta1_mkdf/start.S
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
.section ".text.init"
|
||||
.globl _start
|
||||
_start:
|
||||
li x1, 0
|
||||
li x2, 0
|
||||
li x3, 0
|
||||
li x4, 0
|
||||
li x5, 0
|
||||
li x6, 0
|
||||
li x7, 0
|
||||
li x8, 0
|
||||
li x9, 0
|
||||
li x10,0
|
||||
li x11,0
|
||||
li x12,0
|
||||
li x13,0
|
||||
li x14,0
|
||||
li x15,0
|
||||
li x16,0
|
||||
li x17,0
|
||||
li x18,0
|
||||
li x19,0
|
||||
li x20,0
|
||||
li x21,0
|
||||
li x22,0
|
||||
li x23,0
|
||||
li x24,0
|
||||
li x25,0
|
||||
li x26,0
|
||||
li x27,0
|
||||
li x28,0
|
||||
li x29,0
|
||||
li x30,0
|
||||
li x31,0
|
||||
|
||||
/* init stack to right under where we load app at 0x40010000 */
|
||||
li sp, 0x4000fff0
|
||||
|
||||
/* copy data section */
|
||||
la a0, _sidata
|
||||
la a1, _sdata
|
||||
la a2, _edata
|
||||
bge a1, a2, end_init_data
|
||||
|
||||
loop_init_data:
|
||||
lw a3, 0(a0)
|
||||
sw a3, 0(a1)
|
||||
addi a0, a0, 4
|
||||
addi a1, a1, 4
|
||||
blt a1, a2, loop_init_data
|
||||
|
||||
end_init_data:
|
||||
/* zero-init bss section */
|
||||
la a0, _sbss
|
||||
la a1, _ebss
|
||||
bge a0, a1, end_init_bss
|
||||
|
||||
loop_init_bss:
|
||||
sw zero, 0(a0)
|
||||
addi a0, a0, 4
|
||||
blt a0, a1, loop_init_bss
|
||||
|
||||
end_init_bss:
|
||||
call main
|
||||
|
||||
loop:
|
||||
j loop
|
19
hw/application_fpga/fw/mta1_mkdf/types.h
Normal file
19
hw/application_fpga/fw/mta1_mkdf/types.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
typedef unsigned int uintptr_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef int int32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned long size_t;
|
||||
|
||||
#define NULL ((char *)0)
|
||||
|
||||
#endif
|
109
hw/application_fpga/fw/mta1_mkdf_mem.h
Normal file
109
hw/application_fpga/fw/mta1_mkdf_mem.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* QEMU RISC-V Board Compatible with Mullvad MTA1-MKDF platform
|
||||
*
|
||||
* Copyright (c) 2022 Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef HW_MTA1_MKDF_MEM_H
|
||||
#define HW_MTA1_MKDF_MEM_H
|
||||
|
||||
// The canonical location of this file is:
|
||||
// repo: https://github.com/tillitis/tillitis-key1
|
||||
// path: /hw/application_fpga/fw/mta1_mkdf_mem.h
|
||||
|
||||
// The contents are derived from the Verilog code. For use by QEMU model,
|
||||
// firmware, and apps.
|
||||
|
||||
enum {
|
||||
MTA1_MKDF_ROM_BASE = 0x00000000, // 0b00000000...
|
||||
MTA1_MKDF_RAM_BASE = 0x40000000, // 0b01000000...
|
||||
MTA1_MKDF_RESERVED_BASE = 0x80000000, // 0b10000000...
|
||||
MTA1_MKDF_MMIO_BASE = 0xc0000000, // 0b11000000...
|
||||
MTA1_MKDF_MMIO_SIZE = 0xffffffff - MTA1_MKDF_MMIO_BASE,
|
||||
|
||||
MTA1_MKDF_MMIO_TRNG_BASE = MTA1_MKDF_MMIO_BASE | 0x00000000,
|
||||
MTA1_MKDF_MMIO_TIMER_BASE = MTA1_MKDF_MMIO_BASE | 0x01000000,
|
||||
MTA1_MKDF_MMIO_UDS_BASE = MTA1_MKDF_MMIO_BASE | 0x02000000,
|
||||
MTA1_MKDF_MMIO_UART_BASE = MTA1_MKDF_MMIO_BASE | 0x03000000,
|
||||
MTA1_MKDF_MMIO_TOUCH_BASE = MTA1_MKDF_MMIO_BASE | 0x04000000,
|
||||
// This "core" only exists in QEMU
|
||||
MTA1_MKDF_MMIO_QEMU_BASE = MTA1_MKDF_MMIO_BASE | 0x3e000000,
|
||||
MTA1_MKDF_MMIO_MTA1_BASE = MTA1_MKDF_MMIO_BASE | 0x3f000000, // 0xff000000
|
||||
|
||||
MTA1_MKDF_NAME0_SUFFIX = 0x00,
|
||||
MTA1_MKDF_NAME1_SUFFIX = 0x04,
|
||||
MTA1_MKDF_VERSION_SUFFIX = 0x08,
|
||||
|
||||
MTA1_MKDF_MMIO_TRNG_NAME0 = MTA1_MKDF_MMIO_TRNG_BASE | MTA1_MKDF_NAME0_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TRNG_NAME1 = MTA1_MKDF_MMIO_TRNG_BASE | MTA1_MKDF_NAME1_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TRNG_VERSION = MTA1_MKDF_MMIO_TRNG_BASE | MTA1_MKDF_VERSION_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TRNG_STATUS = MTA1_MKDF_MMIO_TRNG_BASE | 0x24,
|
||||
MTA1_MKDF_MMIO_TRNG_STATUS_READY_BIT = 0,
|
||||
MTA1_MKDF_MMIO_TRNG_SAMPLE_RATE = MTA1_MKDF_MMIO_TRNG_BASE | 0x40,
|
||||
MTA1_MKDF_MMIO_TRNG_ENTROPY = MTA1_MKDF_MMIO_TRNG_BASE | 0x80,
|
||||
|
||||
MTA1_MKDF_MMIO_TIMER_NAME0 = MTA1_MKDF_MMIO_TIMER_BASE | MTA1_MKDF_NAME0_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TIMER_NAME1 = MTA1_MKDF_MMIO_TIMER_BASE | MTA1_MKDF_NAME1_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TIMER_VERSION = MTA1_MKDF_MMIO_TIMER_BASE | MTA1_MKDF_VERSION_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TIMER_CTRL = MTA1_MKDF_MMIO_TIMER_BASE | 0x20,
|
||||
MTA1_MKDF_MMIO_TIMER_CTRL_START_BIT = 0,
|
||||
MTA1_MKDF_MMIO_TIMER_CTRL_STOP_BIT = 1,
|
||||
MTA1_MKDF_MMIO_TIMER_STATUS = MTA1_MKDF_MMIO_TIMER_BASE | 0x24,
|
||||
MTA1_MKDF_MMIO_TIMER_STATUS_READY_BIT = 0,
|
||||
MTA1_MKDF_MMIO_TIMER_PRESCALER = MTA1_MKDF_MMIO_TIMER_BASE | 0x28,
|
||||
MTA1_MKDF_MMIO_TIMER_TIMER = MTA1_MKDF_MMIO_TIMER_BASE | 0x2c,
|
||||
|
||||
MTA1_MKDF_MMIO_UDS_NAME0 = MTA1_MKDF_MMIO_UDS_BASE | MTA1_MKDF_NAME0_SUFFIX,
|
||||
MTA1_MKDF_MMIO_UDS_NAME1 = MTA1_MKDF_MMIO_UDS_BASE | MTA1_MKDF_NAME1_SUFFIX,
|
||||
MTA1_MKDF_MMIO_UDS_VERSION = MTA1_MKDF_MMIO_UDS_BASE | MTA1_MKDF_VERSION_SUFFIX,
|
||||
MTA1_MKDF_MMIO_UDS_FIRST = MTA1_MKDF_MMIO_UDS_BASE | 0x40,
|
||||
MTA1_MKDF_MMIO_UDS_LAST = MTA1_MKDF_MMIO_UDS_BASE | 0x5c, // Address of last 32-bit word of UDS
|
||||
|
||||
MTA1_MKDF_MMIO_UART_NAME0 = MTA1_MKDF_MMIO_UART_BASE | MTA1_MKDF_NAME0_SUFFIX,
|
||||
MTA1_MKDF_MMIO_UART_NAME1 = MTA1_MKDF_MMIO_UART_BASE | MTA1_MKDF_NAME1_SUFFIX,
|
||||
MTA1_MKDF_MMIO_UART_VERSION = MTA1_MKDF_MMIO_UART_BASE | MTA1_MKDF_VERSION_SUFFIX,
|
||||
MTA1_MKDF_MMIO_UART_BIT_RATE = MTA1_MKDF_MMIO_UART_BASE | 0x40,
|
||||
MTA1_MKDF_MMIO_UART_DATA_BITS = MTA1_MKDF_MMIO_UART_BASE | 0x44,
|
||||
MTA1_MKDF_MMIO_UART_STOP_BITS = MTA1_MKDF_MMIO_UART_BASE | 0x48,
|
||||
MTA1_MKDF_MMIO_UART_RX_STATUS = MTA1_MKDF_MMIO_UART_BASE | 0x80,
|
||||
MTA1_MKDF_MMIO_UART_RX_DATA = MTA1_MKDF_MMIO_UART_BASE | 0x84,
|
||||
MTA1_MKDF_MMIO_UART_TX_STATUS = MTA1_MKDF_MMIO_UART_BASE | 0x100,
|
||||
MTA1_MKDF_MMIO_UART_TX_DATA = MTA1_MKDF_MMIO_UART_BASE | 0x104,
|
||||
|
||||
MTA1_MKDF_MMIO_TOUCH_NAME0 = MTA1_MKDF_MMIO_TOUCH_BASE | MTA1_MKDF_NAME0_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TOUCH_NAME1 = MTA1_MKDF_MMIO_TOUCH_BASE | MTA1_MKDF_NAME1_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TOUCH_VERSION = MTA1_MKDF_MMIO_TOUCH_BASE | MTA1_MKDF_VERSION_SUFFIX,
|
||||
MTA1_MKDF_MMIO_TOUCH_STATUS = MTA1_MKDF_MMIO_TOUCH_BASE | 0x24,
|
||||
MTA1_MKDF_MMIO_TOUCH_STATUS_EVENT_BIT = 0,
|
||||
|
||||
// TODO HW core/addr is not yet defined for this:
|
||||
MTA1_MKDF_MMIO_QEMU_UDA = MTA1_MKDF_MMIO_QEMU_BASE | 0x20,
|
||||
// This will only ever exist in QEMU:
|
||||
MTA1_MKDF_MMIO_QEMU_DEBUG = MTA1_MKDF_MMIO_QEMU_BASE | 0x1000,
|
||||
|
||||
MTA1_MKDF_MMIO_MTA1_NAME0 = MTA1_MKDF_MMIO_MTA1_BASE | MTA1_MKDF_NAME0_SUFFIX,
|
||||
MTA1_MKDF_MMIO_MTA1_NAME1 = MTA1_MKDF_MMIO_MTA1_BASE | MTA1_MKDF_NAME1_SUFFIX,
|
||||
MTA1_MKDF_MMIO_MTA1_VERSION = MTA1_MKDF_MMIO_MTA1_BASE | MTA1_MKDF_VERSION_SUFFIX,
|
||||
MTA1_MKDF_MMIO_MTA1_SWITCH_APP = MTA1_MKDF_MMIO_MTA1_BASE | 0x20,
|
||||
MTA1_MKDF_MMIO_MTA1_LED = MTA1_MKDF_MMIO_MTA1_BASE | 0x24,
|
||||
MTA1_MKDF_MMIO_MTA1_LED_R_BIT = 2,
|
||||
MTA1_MKDF_MMIO_MTA1_LED_G_BIT = 1,
|
||||
MTA1_MKDF_MMIO_MTA1_LED_B_BIT = 0,
|
||||
MTA1_MKDF_MMIO_MTA1_GPIO = MTA1_MKDF_MMIO_MTA1_BASE | 0x28,
|
||||
MTA1_MKDF_MMIO_MTA1_GPIO1_BIT = 0,
|
||||
MTA1_MKDF_MMIO_MTA1_GPIO2_BIT = 1,
|
||||
MTA1_MKDF_MMIO_MTA1_GPIO3_BIT = 2,
|
||||
MTA1_MKDF_MMIO_MTA1_GPIO4_BIT = 3,
|
||||
MTA1_MKDF_MMIO_MTA1_APP_ADDR = MTA1_MKDF_MMIO_MTA1_BASE | 0x30, // 0x4000_0000
|
||||
MTA1_MKDF_MMIO_MTA1_APP_SIZE = MTA1_MKDF_MMIO_MTA1_BASE | 0x34,
|
||||
MTA1_MKDF_MMIO_MTA1_DEBUG = MTA1_MKDF_MMIO_MTA1_BASE | 0x40,
|
||||
MTA1_MKDF_MMIO_MTA1_CDI_FIRST = MTA1_MKDF_MMIO_MTA1_BASE | 0x80,
|
||||
MTA1_MKDF_MMIO_MTA1_CDI_LAST = MTA1_MKDF_MMIO_MTA1_BASE | 0x9c, // Address of last 32-bit word of CDI.
|
||||
MTA1_MKDF_MMIO_MTA1_UDI_FIRST = MTA1_MKDF_MMIO_MTA1_BASE | 0xc0,
|
||||
MTA1_MKDF_MMIO_MTA1_UDI_LAST = MTA1_MKDF_MMIO_MTA1_BASE | 0xc4, // Address of last 32-bit word of UDI.
|
||||
};
|
||||
|
||||
#endif
|
4
hw/application_fpga/fw/testfw/Makefile
Normal file
4
hw/application_fpga/fw/testfw/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
.PHONY: fmt
|
||||
fmt:
|
||||
# Uses ../.clang-format
|
||||
clang-format --verbose -i main.c
|
171
hw/application_fpga/fw/testfw/main.c
Normal file
171
hw/application_fpga/fw/testfw/main.c
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - Tillitis AB
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "../mta1_mkdf/lib.h"
|
||||
#include "../mta1_mkdf/proto.h"
|
||||
#include "../mta1_mkdf/types.h"
|
||||
#include "../mta1_mkdf_mem.h"
|
||||
|
||||
// clang-format off
|
||||
volatile uint32_t *mta1name0 = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_NAME0;
|
||||
volatile uint32_t *mta1name1 = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_NAME1;
|
||||
volatile uint32_t *uds = (volatile uint32_t *)MTA1_MKDF_MMIO_UDS_FIRST;
|
||||
volatile uint32_t *uda = (volatile uint32_t *)MTA1_MKDF_MMIO_QEMU_UDA; // Only in QEMU right now
|
||||
volatile uint32_t *cdi = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_CDI_FIRST;
|
||||
volatile uint32_t *udi = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_UDI_FIRST;
|
||||
volatile uint32_t *switch_app = (volatile uint32_t *)MTA1_MKDF_MMIO_MTA1_SWITCH_APP;
|
||||
// clang-format on
|
||||
|
||||
// TODO Real UDA is 4 words (16 bytes)
|
||||
#define UDA_WORDS 1
|
||||
|
||||
void test_puts(char *reason)
|
||||
{
|
||||
for (char *c = reason; *c != '\0'; c++) {
|
||||
writebyte(*c);
|
||||
}
|
||||
}
|
||||
|
||||
void test_putsn(char *p, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
writebyte(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_puthex(uint8_t c)
|
||||
{
|
||||
unsigned int upper = (c >> 4) & 0xf;
|
||||
unsigned int lower = c & 0xf;
|
||||
writebyte(upper < 10 ? '0' + upper : 'a' - 10 + upper);
|
||||
writebyte(lower < 10 ? '0' + lower : 'a' - 10 + lower);
|
||||
}
|
||||
|
||||
void test_puthexn(uint8_t *p, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
test_puthex(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_reverseword(uint32_t *wordp)
|
||||
{
|
||||
*wordp = ((*wordp & 0xff000000) >> 24) | ((*wordp & 0x00ff0000) >> 8) |
|
||||
((*wordp & 0x0000ff00) << 8) | ((*wordp & 0x000000ff) << 24);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
uint8_t in;
|
||||
|
||||
// Wait for terminal program and a character to be typed
|
||||
in = readbyte();
|
||||
|
||||
test_puts("Hello, I'm testfw on:");
|
||||
// Output the MTA1 core's NAME0 and NAME1
|
||||
uint32_t name;
|
||||
wordcpy(&name, (void *)mta1name0, 1);
|
||||
test_reverseword(&name);
|
||||
test_putsn((char *)&name, 4);
|
||||
test_puts(" ");
|
||||
wordcpy(&name, (void *)mta1name1, 1);
|
||||
test_reverseword(&name);
|
||||
test_putsn((char *)&name, 4);
|
||||
test_puts("\r\n");
|
||||
|
||||
int anyfailed = 0;
|
||||
|
||||
uint32_t uds_local[8];
|
||||
uint32_t uds_zeros[8];
|
||||
memset(uds_zeros, 0, 8 * 4);
|
||||
// Should get non-empty UDS
|
||||
wordcpy(uds_local, (void *)uds, 8);
|
||||
if (memeq(uds_local, uds_zeros, 8 * 4)) {
|
||||
test_puts("FAIL: UDS empty!\r\n");
|
||||
anyfailed = 1;
|
||||
}
|
||||
// Should NOT be able to read from UDS again
|
||||
wordcpy(uds_local, (void *)uds, 8);
|
||||
if (!memeq(uds_local, uds_zeros, 8 * 4)) {
|
||||
test_puts("FAIL: Could read UDS a second time!\r\n");
|
||||
anyfailed = 1;
|
||||
}
|
||||
|
||||
// TODO test UDA once we have it in real hw
|
||||
// uint32_t uda_local[UDA_WORDS];
|
||||
// uint32_t uda_zeros[UDA_WORDS];
|
||||
// memset(uda_zeros, 0, UDA_WORDS*4);
|
||||
// // Should get non-empty UDA
|
||||
// wordcpy(uda_local, (void *)uda, UDA_WORDS);
|
||||
// if (memeq(uda_local, uda_zeros, UDA_WORDS*4)) {
|
||||
// test_puts("FAIL: UDA empty!\r\n");
|
||||
// anyfailed = 1;
|
||||
// }
|
||||
|
||||
uint32_t udi_local[2];
|
||||
uint32_t udi_zeros[2];
|
||||
memset(udi_zeros, 0, 2 * 4);
|
||||
// Should get non-empty UDI
|
||||
wordcpy(udi_local, (void *)udi, 2);
|
||||
if (memeq(udi_local, udi_zeros, 2 * 4)) {
|
||||
test_puts("FAIL: UDI empty!\r\n");
|
||||
anyfailed = 1;
|
||||
}
|
||||
|
||||
// Should be able to write to CDI in non-app mode.
|
||||
uint32_t cdi_writetest[8] = {0xdeafbeef, 0xdeafbeef, 0xdeafbeef,
|
||||
0xdeafbeef, 0xdeafbeef, 0xdeafbeef,
|
||||
0xdeafbeef, 0xdeafbeef};
|
||||
uint32_t cdi_readback[8];
|
||||
wordcpy((void *)cdi, cdi_writetest, 8);
|
||||
wordcpy(cdi_readback, (void *)cdi, 8);
|
||||
if (!memeq(cdi_writetest, cdi_readback, 8 * 4)) {
|
||||
test_puts("FAIL: Could not write to CDI in non-app mode!\r\n");
|
||||
anyfailed = 1;
|
||||
}
|
||||
|
||||
// Turn on application mode
|
||||
*switch_app = 1;
|
||||
|
||||
// Should NOT be able to read from UDS in app-mode.
|
||||
wordcpy(uds_local, (void *)uds, 8);
|
||||
if (!memeq(uds_local, uds_zeros, 8 * 4)) {
|
||||
test_puts("FAIL: Could read from UDS in app-mode!\r\n");
|
||||
anyfailed = 1;
|
||||
}
|
||||
|
||||
// TODO test UDA once we have in in real hw
|
||||
// // Now we should NOT be able to read from UDA.
|
||||
// wordcpy(uda_local, (void *)uda, UDA_WORDS);
|
||||
// if (!memeq(uda_local, uda_zeros, UDA_WORDS*4)) {
|
||||
// test_puts("FAIL: Could read from UDA in app-mode!\r\n");
|
||||
// anyfailed = 1;
|
||||
// }
|
||||
|
||||
uint32_t cdi_local[8];
|
||||
uint32_t cdi_local2[8];
|
||||
uint32_t cdi_zeros[8];
|
||||
memset(cdi_zeros, 0, 8 * 4);
|
||||
wordcpy(cdi_local, (void *)cdi, 8);
|
||||
// Write to CDI should NOT have any effect in app mode.
|
||||
wordcpy((void *)cdi, cdi_zeros, 8);
|
||||
wordcpy(cdi_local2, (void *)cdi, 8);
|
||||
if (!memeq(cdi_local, cdi_local2, 8 * 4)) {
|
||||
test_puts("FAIL: Could write to CDI in app-mode!\r\n");
|
||||
anyfailed = 1;
|
||||
}
|
||||
|
||||
if (anyfailed) {
|
||||
test_puts("Some test failed!\r\n");
|
||||
} else {
|
||||
test_puts("All tests passed.\r\n");
|
||||
}
|
||||
|
||||
test_puts("Now echoing what you type...\r\n");
|
||||
for (;;) {
|
||||
in = readbyte(); // blocks
|
||||
writebyte(in);
|
||||
}
|
||||
}
|
467
hw/application_fpga/rtl/application_fpga.v
Normal file
467
hw/application_fpga/rtl/application_fpga.v
Normal file
|
@ -0,0 +1,467 @@
|
|||
//======================================================================
|
||||
//
|
||||
// application_fpga.v
|
||||
// ------------------
|
||||
// Top level module of the application FPGA.
|
||||
// The design exposes a UART interface to allow a host to
|
||||
// send commands and receive resposes as needed load, execute and
|
||||
// communicate with applications.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module application_fpga(
|
||||
output wire interface_rx,
|
||||
input wire interface_tx,
|
||||
|
||||
input wire touch_event,
|
||||
|
||||
input wire app_gpio1,
|
||||
input wire app_gpio2,
|
||||
output wire app_gpio3,
|
||||
output wire app_gpio4,
|
||||
|
||||
output wire led_r,
|
||||
output wire led_g,
|
||||
output wire led_b
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Local parameters
|
||||
//----------------------------------------------------------------
|
||||
// Top level mem area prefixes.
|
||||
localparam ROM_PREFIX = 2'h0;
|
||||
localparam RAM_PREFIX = 2'h1;
|
||||
localparam RESERVED_PREFIX = 2'h2;
|
||||
localparam MMIO_PREFIX = 2'h3;
|
||||
|
||||
// MMIO core sub-prefixes.
|
||||
localparam TRNG_PREFIX = 6'h00;
|
||||
localparam TIMER_PREFIX = 6'h01;
|
||||
localparam UDS_PREFIX = 6'h02;
|
||||
localparam UART_PREFIX = 6'h03;
|
||||
localparam TOUCH_SENSE_PREFIX = 6'h04;
|
||||
localparam MTA1_PREFIX = 6'h3f;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers, memories with associated wires.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] muxed_rdata_reg;
|
||||
reg [31 : 0] muxed_rdata_new;
|
||||
|
||||
reg muxed_ready_reg;
|
||||
reg muxed_ready_new;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
wire clk;
|
||||
wire reset_n;
|
||||
|
||||
wire cpu_valid;
|
||||
wire [03 : 0] cpu_wstrb;
|
||||
wire [31 : 0] cpu_addr;
|
||||
wire [31 : 0] cpu_wdata;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg rom_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg [11 : 0] rom_address;
|
||||
wire [31 : 0] rom_read_data;
|
||||
wire rom_ready;
|
||||
|
||||
reg ram_cs;
|
||||
reg [3 : 0] ram_we;
|
||||
reg [14 : 0] ram_address;
|
||||
reg [31 : 0] ram_write_data;
|
||||
wire [31 : 0] ram_read_data;
|
||||
wire ram_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg trng_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg trng_we;
|
||||
reg [7 : 0] trng_address;
|
||||
reg [31 : 0] trng_write_data;
|
||||
wire [31 : 0] trng_read_data;
|
||||
wire trng_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg timer_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg timer_we;
|
||||
reg [7 : 0] timer_address;
|
||||
reg [31 : 0] timer_write_data;
|
||||
wire [31 : 0] timer_read_data;
|
||||
wire timer_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg uds_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg [7 : 0] uds_address;
|
||||
wire [31 : 0] uds_read_data;
|
||||
wire uds_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg uart_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg uart_we;
|
||||
reg [7 : 0] uart_address;
|
||||
reg [31 : 0] uart_write_data;
|
||||
wire [31 : 0] uart_read_data;
|
||||
wire uart_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg touch_sense_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg touch_sense_we;
|
||||
reg [7 : 0] touch_sense_address;
|
||||
wire [31 : 0] touch_sense_read_data;
|
||||
wire touch_sense_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg mta1_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg mta1_we;
|
||||
reg [7 : 0] mta1_address;
|
||||
reg [31 : 0] mta1_write_data;
|
||||
wire [31 : 0] mta1_read_data;
|
||||
wire mta1_ready;
|
||||
wire fw_app_mode;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent assignments.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Module instantiations.
|
||||
//----------------------------------------------------------------
|
||||
// Use the FPGA internal High Frequency OSCillator as clock source.
|
||||
// 00: 48MHz, 01: 24MHz, 10: 12MHz, 11: 6MHz
|
||||
SB_HFOSC #(.CLKHF_DIV("0b10")
|
||||
) u_hfosc (.CLKHFPU(1'b1),.CLKHFEN(1'b1),.CLKHF(clk));
|
||||
|
||||
|
||||
reset_gen #(.RESET_CYCLES(200))
|
||||
reset_gen_inst(.clk(clk), .rst_n(reset_n));
|
||||
|
||||
|
||||
picorv32 #(
|
||||
.ENABLE_COUNTERS(0),
|
||||
.LATCHED_MEM_RDATA(0),
|
||||
.TWO_STAGE_SHIFT(0),
|
||||
.TWO_CYCLE_ALU(0),
|
||||
.CATCH_MISALIGN(0),
|
||||
.CATCH_ILLINSN(0),
|
||||
.COMPRESSED_ISA(1),
|
||||
.ENABLE_FAST_MUL(1),
|
||||
.ENABLE_DIV(0),
|
||||
.BARREL_SHIFTER(1)
|
||||
) cpu(
|
||||
.clk(clk),
|
||||
.resetn(reset_n),
|
||||
|
||||
.mem_valid(cpu_valid),
|
||||
.mem_ready(muxed_ready_reg),
|
||||
.mem_addr (cpu_addr),
|
||||
.mem_wdata(cpu_wdata),
|
||||
.mem_wstrb(cpu_wstrb),
|
||||
.mem_rdata(muxed_rdata_reg),
|
||||
|
||||
// Defined unsed ports. Makes lint happy,
|
||||
// but still needs to help lint with empty ports.
|
||||
/* verilator lint_off PINCONNECTEMPTY */
|
||||
.irq(32'h0),
|
||||
.eoi(),
|
||||
.trap(),
|
||||
.trace_valid(),
|
||||
.trace_data(),
|
||||
.mem_instr(),
|
||||
.mem_la_read(),
|
||||
.mem_la_write(),
|
||||
.mem_la_addr(),
|
||||
.mem_la_wdata(),
|
||||
.mem_la_wstrb(),
|
||||
.pcpi_valid(),
|
||||
.pcpi_insn(),
|
||||
.pcpi_rs1(),
|
||||
.pcpi_rs2(),
|
||||
.pcpi_wr(1'h0),
|
||||
.pcpi_rd(32'h0),
|
||||
.pcpi_wait(1'h0),
|
||||
.pcpi_ready(1'h0)
|
||||
/* verilator lint_on PINCONNECTEMPTY */
|
||||
);
|
||||
|
||||
|
||||
rom rom_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.cs(rom_cs),
|
||||
.address(rom_address),
|
||||
.read_data(rom_read_data),
|
||||
.ready(rom_ready)
|
||||
);
|
||||
|
||||
|
||||
ram ram_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.cs(ram_cs),
|
||||
.we(ram_we),
|
||||
.address(ram_address),
|
||||
.write_data(ram_write_data),
|
||||
.read_data(ram_read_data),
|
||||
.ready(ram_ready)
|
||||
);
|
||||
|
||||
|
||||
figaro trng_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.cs(trng_cs),
|
||||
.we(trng_we),
|
||||
.address(trng_address),
|
||||
.write_data(trng_write_data),
|
||||
.read_data(trng_read_data),
|
||||
.ready(trng_ready)
|
||||
);
|
||||
|
||||
|
||||
timer timer_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.cs(timer_cs),
|
||||
.we(timer_we),
|
||||
.address(timer_address),
|
||||
.write_data(timer_write_data),
|
||||
.read_data(timer_read_data),
|
||||
.ready(timer_ready)
|
||||
);
|
||||
|
||||
|
||||
uds uds_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.fw_app_mode(fw_app_mode),
|
||||
|
||||
.cs(uds_cs),
|
||||
.address(uds_address),
|
||||
.read_data(uds_read_data),
|
||||
.ready(uds_ready)
|
||||
);
|
||||
|
||||
|
||||
uart uart_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.rxd(interface_tx),
|
||||
.txd(interface_rx),
|
||||
|
||||
.cs(uart_cs),
|
||||
.we(uart_we),
|
||||
.address(uart_address),
|
||||
.write_data(uart_write_data),
|
||||
.read_data(uart_read_data),
|
||||
.ready(uart_ready)
|
||||
);
|
||||
|
||||
|
||||
touch_sense touch_sense_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.touch_event(touch_event),
|
||||
|
||||
.cs(touch_sense_cs),
|
||||
.we(touch_sense_we),
|
||||
.address(touch_sense_address),
|
||||
.read_data(touch_sense_read_data),
|
||||
.ready(touch_sense_ready)
|
||||
);
|
||||
|
||||
|
||||
mta1 mta1_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.fw_app_mode(fw_app_mode),
|
||||
|
||||
.led_r(led_r),
|
||||
.led_g(led_g),
|
||||
.led_b(led_b),
|
||||
|
||||
.gpio1(app_gpio1),
|
||||
.gpio2(app_gpio2),
|
||||
.gpio3(app_gpio3),
|
||||
.gpio4(app_gpio4),
|
||||
|
||||
.cs(mta1_cs),
|
||||
.we(mta1_we),
|
||||
.address(mta1_address),
|
||||
.write_data(mta1_write_data),
|
||||
.read_data(mta1_read_data),
|
||||
.ready(mta1_ready)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Reg_update.
|
||||
// Posedge triggered with synchronous, active low reset.
|
||||
//----------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
if (!reset_n) begin
|
||||
muxed_rdata_reg <= 32'h0;
|
||||
muxed_ready_reg <= 1'h0;
|
||||
end
|
||||
|
||||
else begin
|
||||
muxed_rdata_reg <= muxed_rdata_new;
|
||||
muxed_ready_reg <= muxed_ready_new;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// cpu_mem_ctrl
|
||||
// CPU memory decode and control logic.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : cpu_mem_ctrl
|
||||
reg [1 : 0] area_prefix;
|
||||
reg [5 : 0] core_prefix;
|
||||
|
||||
area_prefix = cpu_addr[31 : 30];
|
||||
core_prefix = cpu_addr[29 : 24];
|
||||
|
||||
muxed_ready_new = 1'h0;
|
||||
muxed_rdata_new = 32'h0;
|
||||
|
||||
rom_cs = 1'h0;
|
||||
rom_address = cpu_addr[13 : 2];
|
||||
|
||||
ram_cs = 1'h0;
|
||||
ram_we = cpu_wstrb;
|
||||
ram_address = cpu_addr[16 : 2];
|
||||
ram_write_data = cpu_wdata;
|
||||
|
||||
trng_cs = 1'h0;
|
||||
trng_we = |cpu_wstrb;
|
||||
trng_address = cpu_addr[10 : 2];
|
||||
trng_write_data = cpu_wdata;
|
||||
|
||||
timer_cs = 1'h0;
|
||||
timer_we = |cpu_wstrb;
|
||||
timer_address = cpu_addr[10 : 2];
|
||||
timer_write_data = cpu_wdata;
|
||||
|
||||
uds_cs = 1'h0;
|
||||
uds_address = cpu_addr[10 : 2];
|
||||
|
||||
uart_cs = 1'h0;
|
||||
uart_we = |cpu_wstrb;
|
||||
uart_address = cpu_addr[10 : 2];
|
||||
uart_write_data = cpu_wdata;
|
||||
|
||||
touch_sense_cs = 1'h0;
|
||||
touch_sense_we = |cpu_wstrb;
|
||||
touch_sense_address = cpu_addr[10 : 2];
|
||||
|
||||
mta1_cs = 1'h0;
|
||||
mta1_we = |cpu_wstrb;
|
||||
mta1_address = cpu_addr[10 : 2];
|
||||
mta1_write_data = cpu_wdata;
|
||||
|
||||
if (cpu_valid && !muxed_ready_reg) begin
|
||||
case (area_prefix)
|
||||
ROM_PREFIX: begin
|
||||
rom_cs = 1'h1;
|
||||
muxed_rdata_new = rom_read_data;
|
||||
muxed_ready_new = rom_ready;
|
||||
end
|
||||
|
||||
RAM_PREFIX: begin
|
||||
ram_cs = 1'h1;
|
||||
muxed_rdata_new = ram_read_data;
|
||||
muxed_ready_new = ram_ready;
|
||||
end
|
||||
|
||||
RESERVED_PREFIX: begin
|
||||
muxed_rdata_new = 32'h0;
|
||||
muxed_ready_new = 1'h1;
|
||||
end
|
||||
|
||||
MMIO_PREFIX: begin
|
||||
case (core_prefix)
|
||||
TRNG_PREFIX: begin
|
||||
trng_cs = 1'h1;
|
||||
muxed_rdata_new = trng_read_data;
|
||||
muxed_ready_new = trng_ready;
|
||||
end
|
||||
|
||||
TIMER_PREFIX: begin
|
||||
timer_cs = 1'h1;
|
||||
muxed_rdata_new = timer_read_data;
|
||||
muxed_ready_new = timer_ready;
|
||||
end
|
||||
|
||||
UDS_PREFIX: begin
|
||||
uds_cs = 1'h1;
|
||||
muxed_rdata_new = uds_read_data;
|
||||
muxed_ready_new = uds_ready;
|
||||
end
|
||||
|
||||
UART_PREFIX: begin
|
||||
uart_cs = 1'h1;
|
||||
muxed_rdata_new = uart_read_data;
|
||||
muxed_ready_new = uart_ready;
|
||||
end
|
||||
|
||||
TOUCH_SENSE_PREFIX: begin
|
||||
touch_sense_cs = 1'h1;
|
||||
muxed_rdata_new = touch_sense_read_data;
|
||||
muxed_ready_new = touch_sense_ready;
|
||||
end
|
||||
|
||||
MTA1_PREFIX: begin
|
||||
mta1_cs = 1'h1;
|
||||
muxed_rdata_new = mta1_read_data;
|
||||
muxed_ready_new = mta1_ready;
|
||||
end
|
||||
|
||||
default: begin
|
||||
muxed_rdata_new = 32'h0;
|
||||
muxed_ready_new = 1'h1;
|
||||
end
|
||||
endcase // case (core_prefix)
|
||||
end // case: MMIO_PREFIX
|
||||
|
||||
default: begin
|
||||
muxed_rdata_new = 32'h0;
|
||||
muxed_ready_new = 1'h1;
|
||||
end
|
||||
endcase // case (area_prefix)
|
||||
end
|
||||
end
|
||||
endmodule // application_fpga
|
||||
|
||||
//======================================================================
|
||||
// EOF application_fpga.v
|
||||
//======================================================================
|
144
hw/application_fpga/rtl/ram.v
Normal file
144
hw/application_fpga/rtl/ram.v
Normal file
|
@ -0,0 +1,144 @@
|
|||
//======================================================================
|
||||
//
|
||||
// ram.v
|
||||
// -----
|
||||
// Module that encapsulates the four SPRAM blocks in the Lattice
|
||||
// iCE40UP 5K device. This creates a single 32-bit wide,
|
||||
// 128 kByte large memory.
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module ram(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire cs,
|
||||
input wire [03 : 0] we,
|
||||
input wire [14 : 0] address,
|
||||
input wire [31 : 0] write_data,
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers and wires.
|
||||
//----------------------------------------------------------------
|
||||
reg ready_reg;
|
||||
|
||||
reg cs0;
|
||||
reg cs1;
|
||||
reg [31 : 0] read_data0;
|
||||
reg [31 : 0] read_data1;
|
||||
reg [31 : 0] muxed_read_data;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent assignment of ports.
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = muxed_read_data;
|
||||
assign ready = ready_reg;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// SPRAM instances.
|
||||
//----------------------------------------------------------------
|
||||
SB_SPRAM256KA spram0(
|
||||
.ADDRESS(address[13:0]),
|
||||
.DATAIN(write_data[15:0]),
|
||||
.MASKWREN({we[1], we[1], we[0], we[0]}),
|
||||
.WREN(we[1] | we[0]),
|
||||
.CHIPSELECT(cs0),
|
||||
.CLOCK(clk),
|
||||
.STANDBY(1'b0),
|
||||
.SLEEP(1'b0),
|
||||
.POWEROFF(1'b1),
|
||||
.DATAOUT(read_data0[15:0])
|
||||
);
|
||||
|
||||
SB_SPRAM256KA spram1(
|
||||
.ADDRESS(address[13:0]),
|
||||
.DATAIN(write_data[31:16]),
|
||||
.MASKWREN({we[3], we[3], we[2], we[2]}),
|
||||
.WREN(we[3] | we[2]),
|
||||
.CHIPSELECT(cs0),
|
||||
.CLOCK(clk),
|
||||
.STANDBY(1'b0),
|
||||
.SLEEP(1'b0),
|
||||
.POWEROFF(1'b1),
|
||||
.DATAOUT(read_data0[31:16])
|
||||
);
|
||||
|
||||
|
||||
SB_SPRAM256KA spram2(
|
||||
.ADDRESS(address[13:0]),
|
||||
.DATAIN(write_data[15:0]),
|
||||
.MASKWREN({we[1], we[1], we[0], we[0]}),
|
||||
.WREN(we[1] | we[0]),
|
||||
.CHIPSELECT(cs1),
|
||||
.CLOCK(clk),
|
||||
.STANDBY(1'b0),
|
||||
.SLEEP(1'b0),
|
||||
.POWEROFF(1'b1),
|
||||
.DATAOUT(read_data1[15:0])
|
||||
);
|
||||
|
||||
SB_SPRAM256KA spram3(
|
||||
.ADDRESS(address[13:0]),
|
||||
.DATAIN(write_data[31:16]),
|
||||
.MASKWREN({we[3], we[3], we[2], we[2]}),
|
||||
.WREN(we[3] | we[2]),
|
||||
.CHIPSELECT(cs1),
|
||||
.CLOCK(clk),
|
||||
.STANDBY(1'b0),
|
||||
.SLEEP(1'b0),
|
||||
.POWEROFF(1'b1),
|
||||
.DATAOUT(read_data1[31:16])
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update
|
||||
//
|
||||
// Posedge triggered with synchronous, active low reset.
|
||||
// This simply creates a one cycle access latency to match
|
||||
// the latency of the spram blocks.
|
||||
//----------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
if (!reset_n) begin
|
||||
ready_reg <= 1'h0;
|
||||
end
|
||||
else begin
|
||||
ready_reg <= cs;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// mem_mux
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : mem_mux
|
||||
cs0 = 1'h0;
|
||||
cs1 = 1'h0;
|
||||
|
||||
if (address[14]) begin
|
||||
cs1 = cs;
|
||||
muxed_read_data = read_data1;
|
||||
end else begin
|
||||
cs0 = cs;
|
||||
muxed_read_data = read_data0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // ram
|
||||
|
||||
//======================================================================
|
||||
// EOF ram.v
|
||||
//======================================================================
|
72
hw/application_fpga/rtl/reset_gen.v
Normal file
72
hw/application_fpga/rtl/reset_gen.v
Normal file
|
@ -0,0 +1,72 @@
|
|||
//======================================================================
|
||||
//
|
||||
// reset_gen.v
|
||||
// -----------
|
||||
// Reset generator for iCE40 based systems.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module reset_gen #(parameter RESET_CYCLES = 200)
|
||||
(
|
||||
input wire clk,
|
||||
output wire rst_n
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers with associated wires.
|
||||
//----------------------------------------------------------------
|
||||
reg [7 : 0] rst_ctr_reg = 8'h0;
|
||||
reg [7 : 0] rst_ctr_new;
|
||||
reg rst_ctr_we;
|
||||
|
||||
reg rst_n_reg = 1'h0;
|
||||
reg rst_n_new;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent assignment.
|
||||
//----------------------------------------------------------------
|
||||
assign rst_n = rst_n_reg;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update.
|
||||
//----------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
rst_n_reg <= rst_n_new;
|
||||
|
||||
if (rst_ctr_we)
|
||||
rst_ctr_reg <= rst_ctr_new;
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// rst_logic.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : rst_logic
|
||||
rst_n_new = 1'h1;
|
||||
rst_ctr_new = 8'h0;
|
||||
rst_ctr_we = 1'h0;
|
||||
|
||||
if (rst_ctr_reg < RESET_CYCLES) begin
|
||||
rst_n_new = 1'h0;
|
||||
rst_ctr_new = rst_ctr_reg + 1'h1;
|
||||
rst_ctr_we = 1'h1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // reset_gen
|
||||
|
||||
//======================================================================
|
||||
// EOF reset_gen.v
|
||||
//======================================================================
|
67
hw/application_fpga/rtl/rom.v
Normal file
67
hw/application_fpga/rtl/rom.v
Normal file
|
@ -0,0 +1,67 @@
|
|||
//======================================================================
|
||||
//
|
||||
// rom..v
|
||||
// ------
|
||||
// Firmware ROM module. Implemented using Embedded Block RAM
|
||||
// in the FPGA.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module rom(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
input wire cs,
|
||||
input wire [11 : 0] address,
|
||||
output wire [31 : 0] read_data,
|
||||
output wire ready
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers, memories with associated wires.
|
||||
//----------------------------------------------------------------
|
||||
// Size of the sysMem Embedded Block RAM (EBR) memory primarily
|
||||
// used for code storage (ROM). The size is number of
|
||||
// 32-bit words. Each EBR is 4kbit in size, and (at most)
|
||||
// 16-bit wide. Thus means that we use pairs of EBRs, and
|
||||
// each pair store 256 32bit words.
|
||||
// The size of the EBR allocated to memory must match the
|
||||
// size of the firmware file generated by the Makefile.
|
||||
localparam EBR_MEM_SIZE = `BRAM_FW_SIZE;
|
||||
reg [31 : 0] memory [0 : (EBR_MEM_SIZE - 1)];
|
||||
initial $readmemh(`FIRMWARE_HEX, memory);
|
||||
|
||||
reg [31 : 0] rom_rdata;
|
||||
|
||||
reg rom_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent assignments of ports.
|
||||
//----------------------------------------------------------------
|
||||
assign read_data = rom_rdata;
|
||||
assign ready = rom_ready;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// rom_logic
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : rom_logic
|
||||
rom_rdata = memory[address];
|
||||
rom_ready = cs;
|
||||
end
|
||||
|
||||
endmodule // rom
|
||||
|
||||
//======================================================================
|
||||
// EOF rom..v
|
||||
//======================================================================
|
92
hw/application_fpga/rtl/spram.v
Normal file
92
hw/application_fpga/rtl/spram.v
Normal file
|
@ -0,0 +1,92 @@
|
|||
//======================================================================
|
||||
//
|
||||
// spram.v
|
||||
// -------
|
||||
// Module that encapsulates two of the SPRAM blocks in the Lattice
|
||||
// iCE40UP 5K device. This creates a single 32-bit wide,
|
||||
// 64 kByte large memory.
|
||||
//
|
||||
//
|
||||
// Author: Joachim Strombergson
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module spram(
|
||||
input wire clk,
|
||||
input wire rst_n,
|
||||
input wire cs,
|
||||
input wire [03 : 0] wen,
|
||||
input wire [13 : 0] addr,
|
||||
input wire [31 : 0] wdata,
|
||||
output wire ready,
|
||||
output wire [31 : 0] rdata
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers and wires.
|
||||
//----------------------------------------------------------------
|
||||
reg ready_reg;
|
||||
reg ready_new;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
//----------------------------------------------------------------
|
||||
assign ready = ready_reg;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// SPRAM instances.
|
||||
//----------------------------------------------------------------
|
||||
SB_SPRAM256KA spram0(
|
||||
.ADDRESS(addr[13:0]),
|
||||
.DATAIN(wdata[15:0]),
|
||||
.MASKWREN({wen[1], wen[1], wen[0], wen[0]}),
|
||||
.WREN(wen[1]|wen[0]),
|
||||
.CHIPSELECT(cs),
|
||||
.CLOCK(clk),
|
||||
.STANDBY(1'b0),
|
||||
.SLEEP(1'b0),
|
||||
.POWEROFF(1'b1),
|
||||
.DATAOUT(rdata[15:0])
|
||||
);
|
||||
|
||||
SB_SPRAM256KA spram1(
|
||||
.ADDRESS(addr[13:0]),
|
||||
.DATAIN(wdata[31:16]),
|
||||
.MASKWREN({wen[3], wen[3], wen[2], wen[2]}),
|
||||
.WREN(wen[3]|wen[2]),
|
||||
.CHIPSELECT(cs),
|
||||
.CLOCK(clk),
|
||||
.STANDBY(1'b0),
|
||||
.SLEEP(1'b0),
|
||||
.POWEROFF(1'b1),
|
||||
.DATAOUT(rdata[31:16])
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// reg_update.
|
||||
//
|
||||
// Posedge triggered with synchronous, active low reset.
|
||||
// This simply creates a one cycle access delay to allow the
|
||||
// memory access to complete.
|
||||
//----------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
if (!rst_n) begin
|
||||
ready_reg <= 1'h0;
|
||||
end
|
||||
else begin
|
||||
ready_reg <= cs;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // spram
|
||||
|
||||
//======================================================================
|
||||
// EOF spram.v
|
||||
//======================================================================
|
342
hw/application_fpga/tb/application_fpga_verilator.cc
Normal file
342
hw/application_fpga/tb/application_fpga_verilator.cc
Normal file
|
@ -0,0 +1,342 @@
|
|||
//======================================================================
|
||||
//
|
||||
// application_fpga_verilator.cc
|
||||
// -----------------------------
|
||||
// Wrapper to allow simulation of the application_fpga using Verilator.
|
||||
//
|
||||
//
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
#include <pty.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "Vapplication_fpga.h"
|
||||
#include "verilated.h"
|
||||
|
||||
// Joachim says:
|
||||
// Clock: 12 MHz, 38400 bps
|
||||
// Divisor = 12*10E6 / 38400 = 312
|
||||
#define BIT_DIV 312
|
||||
|
||||
struct uart {
|
||||
int bit_div;
|
||||
unsigned int ts;
|
||||
|
||||
unsigned int tx_next_ts;
|
||||
unsigned int rx_next_ts;
|
||||
|
||||
int rx_state; /* 0, (idle), 1 (start), 2..9 (data), 10 (stop), 11 (stop end) */
|
||||
int tx_state; /* 0, (idle), 1..8 (data), 9 (stop), 10 (stop end) */
|
||||
uint8_t tx_data;
|
||||
uint8_t rx_data;
|
||||
int rx_has_data;
|
||||
int tx_has_data;
|
||||
uint8_t *tx;
|
||||
uint8_t *rx;
|
||||
};
|
||||
|
||||
void uart_init(struct uart *u, uint8_t *tx, uint8_t *rx, int bit_div);
|
||||
void uart_tick(struct uart *u);
|
||||
int uart_can_send(struct uart *u);
|
||||
int uart_send(struct uart *u, uint8_t data);
|
||||
int uart_recv(struct uart *u, uint8_t *data);
|
||||
|
||||
void uart_init(struct uart *u, uint8_t *tx, uint8_t *rx, int bit_div)
|
||||
{
|
||||
u->bit_div = bit_div;
|
||||
u->ts = 0;
|
||||
u->tx_next_ts = 0;
|
||||
u->rx_next_ts = 0;
|
||||
u->rx_state = 0;
|
||||
u->tx_state = 0;
|
||||
u->tx_data = 0;
|
||||
u->rx_data = 0;
|
||||
u->rx_has_data = 0;
|
||||
u->tx_has_data = 0;
|
||||
u->tx = tx;
|
||||
*u->tx = 1;
|
||||
u->rx = rx;
|
||||
}
|
||||
|
||||
void uart_rx_tick(struct uart *u)
|
||||
{
|
||||
if (u->rx_state == 0) {
|
||||
// Idle
|
||||
if (!u->rx_has_data && !*u->rx) { // Active low
|
||||
u->rx_next_ts = u->ts + u->bit_div / 2; // sample mid-point
|
||||
u->rx_state = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->rx_state == 1) {
|
||||
// Start
|
||||
if (u->ts < u->rx_next_ts)
|
||||
return;
|
||||
|
||||
if (*u->rx) {
|
||||
u->rx_state = 0; // Back to idle, shouldn't happen
|
||||
return;
|
||||
}
|
||||
|
||||
u->rx_next_ts += u->bit_div;
|
||||
u->rx_data = 0;
|
||||
u->rx_state = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->rx_state > 1 && u->rx_state < 10) {
|
||||
// Data
|
||||
if (u->ts < u->rx_next_ts)
|
||||
return;
|
||||
|
||||
u->rx_next_ts += u->bit_div;
|
||||
u->rx_data |= (!!*u->rx) << (u->rx_state - 2);
|
||||
u->rx_state++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->rx_state == 10) {
|
||||
// Stop
|
||||
if (u->ts < u->rx_next_ts)
|
||||
return;
|
||||
|
||||
if (!*u->rx) {
|
||||
u->rx_state = 0; // Back to dle, shouldn't happen
|
||||
return;
|
||||
}
|
||||
|
||||
u->rx_next_ts += u->bit_div/2;
|
||||
u->rx_has_data = 1;
|
||||
u->rx_state = 11;
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->rx_state == 11) {
|
||||
if (u->ts < u->rx_next_ts)
|
||||
return;
|
||||
|
||||
u->rx_state = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int uart_recv(struct uart *u, uint8_t *data)
|
||||
{
|
||||
if (u->rx_has_data && (u->rx_state == 0 || u->rx_state == 11)) {
|
||||
*data = u->rx_data;
|
||||
u->rx_has_data = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_tx_tick(struct uart *u)
|
||||
{
|
||||
if (u->tx_state == 0) {
|
||||
// Idle
|
||||
if (u->tx_has_data) {
|
||||
u->tx_next_ts = u->ts + u->bit_div;
|
||||
*u->tx = 0; // Start
|
||||
u->tx_state = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->tx_state > 0 && u->tx_state < 9) {
|
||||
// Data
|
||||
if (u->ts < u->tx_next_ts)
|
||||
return;
|
||||
|
||||
u->tx_next_ts += u->bit_div;
|
||||
*u->tx = (u->tx_data >> (u->tx_state - 1)) & 1;
|
||||
u->tx_state++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->tx_state == 9) {
|
||||
// Stop
|
||||
if (u->ts < u->tx_next_ts)
|
||||
return;
|
||||
|
||||
u->tx_next_ts += u->bit_div;
|
||||
*u->tx = 1; // Stop
|
||||
u->tx_has_data = 0;
|
||||
u->tx_state = 10;
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->tx_state == 10) {
|
||||
if (u->ts < u->tx_next_ts)
|
||||
return;
|
||||
|
||||
u->tx_state = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int uart_can_send(struct uart *u)
|
||||
{
|
||||
return !u->tx_has_data;
|
||||
}
|
||||
|
||||
int uart_send(struct uart *u, uint8_t data)
|
||||
{
|
||||
if (!uart_can_send(u))
|
||||
return 0;
|
||||
|
||||
u->tx_has_data = 1;
|
||||
u->tx_data = data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void uart_tick(struct uart *u)
|
||||
{
|
||||
u->ts++;
|
||||
|
||||
uart_rx_tick(u);
|
||||
uart_tx_tick(u);
|
||||
}
|
||||
|
||||
struct pty {
|
||||
int amaster;
|
||||
int aslave;
|
||||
char slave[32];
|
||||
};
|
||||
|
||||
int pty_init(struct pty *p);
|
||||
int pty_can_recv(struct pty *p);
|
||||
int pty_recv(struct pty *p, uint8_t *data);
|
||||
void pty_send(struct pty *p, uint8_t data);
|
||||
|
||||
int pty_init(struct pty *p)
|
||||
{
|
||||
struct termios tty;
|
||||
int flags;
|
||||
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
||||
if (openpty(&p->amaster, &p->aslave, p->slave, NULL, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
if (tcgetattr(p->aslave, &tty) < 0)
|
||||
return -1;
|
||||
cfmakeraw(&tty);
|
||||
if (tcsetattr(p->aslave, TCSAFLUSH, &tty) < 0)
|
||||
return -1;
|
||||
|
||||
if ((flags = fcntl(p->amaster, F_GETFL, 0) < 0))
|
||||
return -1;
|
||||
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(p->amaster, F_SETFL, flags) < 0)
|
||||
return -1;
|
||||
|
||||
printf("pty: %s\n", p->slave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pty_can_recv(struct pty *p)
|
||||
{
|
||||
struct pollfd fds = {p->amaster, POLLIN, 0};
|
||||
char c;
|
||||
|
||||
return poll(&fds, 1, 0) == 1;
|
||||
}
|
||||
|
||||
int pty_recv(struct pty *p, uint8_t *data)
|
||||
{
|
||||
return read(p->amaster, data, 1) == 1;
|
||||
}
|
||||
|
||||
void pty_send(struct pty *p, uint8_t data)
|
||||
{
|
||||
ssize_t i __attribute__((unused));
|
||||
|
||||
i = write(p->amaster, &data, 1);
|
||||
}
|
||||
|
||||
volatile int touch_cyc = 0;
|
||||
|
||||
void sighandler(int)
|
||||
{
|
||||
touch_cyc = 1000;
|
||||
}
|
||||
|
||||
void touch(uint8_t *touch_event)
|
||||
{
|
||||
if (touch_cyc > 0) {
|
||||
touch_cyc--;
|
||||
*touch_event = 1;
|
||||
} else {
|
||||
*touch_event = 0;
|
||||
}
|
||||
}
|
||||
|
||||
vluint64_t main_time = 0;
|
||||
double sc_time_stamp()
|
||||
{
|
||||
return main_time;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env)
|
||||
{
|
||||
Verilated::commandArgs(argc, argv);
|
||||
int r = 0, g = 0, b = 0;
|
||||
Vapplication_fpga top;
|
||||
struct uart u;
|
||||
struct pty p;
|
||||
int err;
|
||||
|
||||
if (signal(SIGUSR1, sighandler) == SIG_ERR)
|
||||
return -1;
|
||||
printf("generate touch event: \"$ kill -USR1 %d\"\n", (int)getpid());
|
||||
|
||||
err = pty_init(&p);
|
||||
if (err)
|
||||
return -1;
|
||||
|
||||
uart_init(&u, &top.interface_tx, &top.interface_rx, BIT_DIV);
|
||||
|
||||
top.clk = 0;
|
||||
|
||||
while (!Verilated::gotFinish()) {
|
||||
uint8_t to_host = 0;
|
||||
|
||||
top.clk = !top.clk;
|
||||
|
||||
if (main_time < 10)
|
||||
goto skip;
|
||||
|
||||
if (!top.clk) {
|
||||
touch(&top.touch_event);
|
||||
uart_tick(&u);
|
||||
}
|
||||
|
||||
if (pty_can_recv(&p) && uart_can_send(&u)) {
|
||||
uint8_t from_host = 0;
|
||||
|
||||
pty_recv(&p, &from_host);
|
||||
uart_send(&u, from_host);
|
||||
}
|
||||
|
||||
if (uart_recv(&u, &to_host) == 1) {
|
||||
pty_send(&p, to_host);
|
||||
}
|
||||
skip:
|
||||
main_time++;
|
||||
top.eval();
|
||||
|
||||
}
|
||||
}
|
482
hw/application_fpga/tb/application_fpga_vsim.v
Normal file
482
hw/application_fpga/tb/application_fpga_vsim.v
Normal file
|
@ -0,0 +1,482 @@
|
|||
//======================================================================
|
||||
//
|
||||
// application_fpga.v
|
||||
// ------------------
|
||||
// Top level module of the application FPGA.
|
||||
// The design exposes a UART interface to allow a host to
|
||||
// send commands and receive resposes as needed load, execute and
|
||||
// communicate with applications.
|
||||
//
|
||||
//
|
||||
// Copyright (C) 2022 - Tillitis AB
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
`default_nettype none
|
||||
|
||||
//`define VERBOSE
|
||||
|
||||
`ifdef VERBOSE
|
||||
`define verbose(debug_command) debug_command
|
||||
`else
|
||||
`define verbose(debug_command)
|
||||
`endif
|
||||
|
||||
|
||||
module application_fpga(
|
||||
input wire clk,
|
||||
|
||||
output wire valid,
|
||||
output wire [03 : 0] wstrb,
|
||||
output wire [31 : 0] addr,
|
||||
output wire [31 : 0] wdata,
|
||||
output wire [31 : 0] rdata,
|
||||
output wire ready,
|
||||
|
||||
output wire interface_rx,
|
||||
input wire interface_tx,
|
||||
|
||||
input wire touch_event,
|
||||
|
||||
input wire app_gpio1,
|
||||
input wire app_gpio2,
|
||||
output wire app_gpio3,
|
||||
output wire app_gpio4,
|
||||
|
||||
output wire led_r,
|
||||
output wire led_g,
|
||||
output wire led_b
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Local parameters
|
||||
//----------------------------------------------------------------
|
||||
// Top level mem area prefixes.
|
||||
localparam ROM_PREFIX = 2'h0;
|
||||
localparam RAM_PREFIX = 2'h1;
|
||||
localparam RESERVED_PREFIX = 2'h2;
|
||||
localparam MMIO_PREFIX = 2'h3;
|
||||
|
||||
// MMIO core mem sub-prefixes.
|
||||
localparam TRNG_PREFIX = 6'h00;
|
||||
localparam TIMER_PREFIX = 6'h01;
|
||||
localparam UDS_PREFIX = 6'h02;
|
||||
localparam UART_PREFIX = 6'h03;
|
||||
localparam TOUCH_SENSE_PREFIX = 6'h04;
|
||||
localparam MTA1_PREFIX = 6'h3f;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Registers, memories with associated wires.
|
||||
//----------------------------------------------------------------
|
||||
reg [31 : 0] muxed_rdata_reg;
|
||||
reg [31 : 0] muxed_rdata_new;
|
||||
|
||||
reg muxed_ready_reg;
|
||||
reg muxed_ready_new;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Wires.
|
||||
//----------------------------------------------------------------
|
||||
wire reset_n;
|
||||
|
||||
wire cpu_valid;
|
||||
wire [03 : 0] cpu_wstrb;
|
||||
wire [31 : 0] cpu_addr;
|
||||
wire [31 : 0] cpu_wdata;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg rom_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg [11 : 0] rom_address;
|
||||
wire [31 : 0] rom_read_data;
|
||||
wire rom_ready;
|
||||
|
||||
reg ram_cs;
|
||||
reg [3 : 0] ram_we;
|
||||
reg [14 : 0] ram_address;
|
||||
reg [31 : 0] ram_write_data;
|
||||
wire [31 : 0] ram_read_data;
|
||||
wire ram_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg trng_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg trng_we;
|
||||
reg [7 : 0] trng_address;
|
||||
reg [31 : 0] trng_write_data;
|
||||
wire [31 : 0] trng_read_data;
|
||||
wire trng_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg timer_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg timer_we;
|
||||
reg [7 : 0] timer_address;
|
||||
reg [31 : 0] timer_write_data;
|
||||
wire [31 : 0] timer_read_data;
|
||||
wire timer_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg uds_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg [7 : 0] uds_address;
|
||||
wire [31 : 0] uds_read_data;
|
||||
wire uds_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg uart_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg uart_we;
|
||||
reg [7 : 0] uart_address;
|
||||
reg [31 : 0] uart_write_data;
|
||||
wire [31 : 0] uart_read_data;
|
||||
wire uart_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg touch_sense_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg touch_sense_we;
|
||||
reg [7 : 0] touch_sense_address;
|
||||
wire [31 : 0] touch_sense_read_data;
|
||||
wire touch_sense_ready;
|
||||
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
reg mta1_cs;
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
reg mta1_we;
|
||||
reg [7 : 0] mta1_address;
|
||||
reg [31 : 0] mta1_write_data;
|
||||
wire [31 : 0] mta1_read_data;
|
||||
wire mta1_ready;
|
||||
wire fw_app_mode;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Concurrent assignments.
|
||||
//----------------------------------------------------------------
|
||||
assign valid = cpu_valid;
|
||||
assign wstrb = cpu_wstrb;
|
||||
assign addr = cpu_addr;
|
||||
assign wdata = cpu_wdata;
|
||||
assign rdata = muxed_rdata_reg;
|
||||
assign ready = muxed_ready_reg;
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Module instantiations.
|
||||
//----------------------------------------------------------------
|
||||
reset_gen #(.RESET_CYCLES(200))
|
||||
reset_gen_inst(.clk(clk), .rst_n(reset_n));
|
||||
|
||||
|
||||
picorv32 #(
|
||||
.ENABLE_COUNTERS(0),
|
||||
.LATCHED_MEM_RDATA(0),
|
||||
.TWO_STAGE_SHIFT(0),
|
||||
.TWO_CYCLE_ALU(0),
|
||||
.CATCH_MISALIGN(0),
|
||||
.CATCH_ILLINSN(0),
|
||||
.COMPRESSED_ISA(1),
|
||||
.ENABLE_MUL(1),
|
||||
.ENABLE_DIV(0),
|
||||
.BARREL_SHIFTER(0)
|
||||
) cpu(
|
||||
.clk(clk),
|
||||
.resetn(reset_n),
|
||||
|
||||
.mem_valid(cpu_valid),
|
||||
.mem_addr (cpu_addr),
|
||||
.mem_wdata(cpu_wdata),
|
||||
.mem_wstrb(cpu_wstrb),
|
||||
.mem_rdata(muxed_rdata_reg),
|
||||
.mem_ready(muxed_ready_reg),
|
||||
|
||||
// Defined unsed ports. Makes lint happy,
|
||||
// but still needs to help lint with empty ports.
|
||||
/* verilator lint_off PINCONNECTEMPTY */
|
||||
.irq(32'h0),
|
||||
.eoi(),
|
||||
.trap(),
|
||||
.trace_valid(),
|
||||
.trace_data(),
|
||||
.mem_instr(),
|
||||
.mem_la_read(),
|
||||
.mem_la_write(),
|
||||
.mem_la_addr(),
|
||||
.mem_la_wdata(),
|
||||
.mem_la_wstrb(),
|
||||
.pcpi_valid(),
|
||||
.pcpi_insn(),
|
||||
.pcpi_rs1(),
|
||||
.pcpi_rs2(),
|
||||
.pcpi_wr(1'h0),
|
||||
.pcpi_rd(32'h0),
|
||||
.pcpi_wait(1'h0),
|
||||
.pcpi_ready(1'h0)
|
||||
/* verilator lint_on PINCONNECTEMPTY */
|
||||
);
|
||||
|
||||
|
||||
rom rom_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.cs(rom_cs),
|
||||
.address(rom_address),
|
||||
.read_data(rom_read_data),
|
||||
.ready(rom_ready)
|
||||
);
|
||||
|
||||
|
||||
ram ram_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.cs(ram_cs),
|
||||
.we(ram_we),
|
||||
.address(ram_address),
|
||||
.write_data(ram_write_data),
|
||||
.read_data(ram_read_data),
|
||||
.ready(ram_ready)
|
||||
);
|
||||
|
||||
|
||||
timer timer_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.cs(timer_cs),
|
||||
.we(timer_we),
|
||||
.address(timer_address),
|
||||
.write_data(timer_write_data),
|
||||
.read_data(timer_read_data),
|
||||
.ready(timer_ready)
|
||||
);
|
||||
|
||||
|
||||
uds uds_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.cs(uds_cs),
|
||||
.address(uds_address),
|
||||
.read_data(uds_read_data),
|
||||
.ready(uds_ready)
|
||||
);
|
||||
|
||||
|
||||
uart uart_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.rxd(interface_tx),
|
||||
.txd(interface_rx),
|
||||
|
||||
.cs(uart_cs),
|
||||
.we(uart_we),
|
||||
.address(uart_address),
|
||||
.write_data(uart_write_data),
|
||||
.read_data(uart_read_data),
|
||||
.ready(uart_ready)
|
||||
);
|
||||
|
||||
|
||||
touch_sense touch_sense_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.touch_event(touch_event),
|
||||
|
||||
.cs(touch_sense_cs),
|
||||
.we(touch_sense_we),
|
||||
.address(touch_sense_address),
|
||||
.read_data(touch_sense_read_data),
|
||||
.ready(touch_sense_ready)
|
||||
);
|
||||
|
||||
|
||||
mta1 mta1_inst(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
.fw_app_mode(fw_app_mode),
|
||||
|
||||
.led_r(led_r),
|
||||
.led_g(led_g),
|
||||
.led_b(led_b),
|
||||
|
||||
.gpio1(app_gpio1),
|
||||
.gpio2(app_gpio2),
|
||||
.gpio3(app_gpio3),
|
||||
.gpio4(app_gpio4),
|
||||
|
||||
.cs(mta1_cs),
|
||||
.we(mta1_we),
|
||||
.address(mta1_address),
|
||||
.write_data(mta1_write_data),
|
||||
.read_data(mta1_read_data),
|
||||
.ready(mta1_ready)
|
||||
);
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Reg_update.
|
||||
// Posedge triggered with synchronous, active low reset.
|
||||
//----------------------------------------------------------------
|
||||
always @(posedge clk)
|
||||
begin : reg_update
|
||||
if (!reset_n) begin
|
||||
muxed_ready_reg <= 1'h0;
|
||||
muxed_rdata_reg <= 32'h0;
|
||||
end
|
||||
|
||||
else begin
|
||||
muxed_ready_reg <= muxed_ready_new;
|
||||
muxed_rdata_reg <= muxed_rdata_new;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// cpu_mem_ctrl
|
||||
// CPU memory decode and control logic.
|
||||
//----------------------------------------------------------------
|
||||
always @*
|
||||
begin : cpu_mem_ctrl
|
||||
reg [1 : 0] area_prefix;
|
||||
reg [5 : 0] core_prefix;
|
||||
|
||||
area_prefix = cpu_addr[31 : 30];
|
||||
core_prefix = cpu_addr[29 : 24];
|
||||
|
||||
muxed_ready_new = 1'h0;
|
||||
muxed_rdata_new = 32'h0;
|
||||
|
||||
rom_cs = 1'h0;
|
||||
rom_address = cpu_addr[13 : 2];
|
||||
|
||||
ram_cs = 1'h0;
|
||||
ram_we = cpu_wstrb;
|
||||
ram_address = cpu_addr[16 : 2];
|
||||
ram_write_data = cpu_wdata;
|
||||
|
||||
trng_cs = 1'h0;
|
||||
trng_we = |cpu_wstrb;
|
||||
trng_address = cpu_addr[10 : 2];
|
||||
trng_write_data = cpu_wdata;
|
||||
|
||||
timer_cs = 1'h0;
|
||||
timer_we = |cpu_wstrb;
|
||||
timer_address = cpu_addr[10 : 2];
|
||||
timer_write_data = cpu_wdata;
|
||||
|
||||
uds_cs = 1'h0;
|
||||
uds_address = cpu_addr[10 : 2];
|
||||
|
||||
uart_cs = 1'h0;
|
||||
uart_we = |cpu_wstrb;
|
||||
uart_address = cpu_addr[10 : 2];
|
||||
uart_write_data = cpu_wdata;
|
||||
|
||||
touch_sense_cs = 1'h0;
|
||||
touch_sense_we = |cpu_wstrb;
|
||||
touch_sense_address = cpu_addr[10 : 2];
|
||||
|
||||
mta1_cs = 1'h0;
|
||||
mta1_we = |cpu_wstrb;
|
||||
mta1_address = cpu_addr[10 : 2];
|
||||
mta1_write_data = cpu_wdata;
|
||||
|
||||
if (cpu_valid && !muxed_ready_reg) begin
|
||||
case (area_prefix)
|
||||
ROM_PREFIX: begin
|
||||
`verbose($display("Access to ROM area");)
|
||||
rom_cs = 1'h1;
|
||||
muxed_rdata_new = rom_read_data;
|
||||
muxed_ready_new = rom_ready;
|
||||
end
|
||||
|
||||
RAM_PREFIX: begin
|
||||
`verbose($display("Access to RAM area");)
|
||||
ram_cs = 1'h1;
|
||||
muxed_rdata_new = ram_read_data;
|
||||
muxed_ready_new = ram_ready;
|
||||
end
|
||||
|
||||
RESERVED_PREFIX: begin
|
||||
`verbose($display("Access to RESERVED area");)
|
||||
muxed_rdata_new = 32'h00000000;
|
||||
muxed_ready_new = 1'h1;
|
||||
end
|
||||
|
||||
MMIO_PREFIX: begin
|
||||
`verbose($display("Access to MMIO area");)
|
||||
case (core_prefix)
|
||||
TRNG_PREFIX: begin
|
||||
`verbose($display("Access to TRNG core");)
|
||||
trng_cs = 1'h1;
|
||||
muxed_rdata_new = trng_read_data;
|
||||
muxed_ready_new = trng_ready;
|
||||
end
|
||||
|
||||
TIMER_PREFIX: begin
|
||||
`verbose($display("Access to TIMER core");)
|
||||
timer_cs = 1'h1;
|
||||
muxed_rdata_new = timer_read_data;
|
||||
muxed_ready_new = timer_ready;
|
||||
end
|
||||
|
||||
UDS_PREFIX: begin
|
||||
`verbose($display("Access to UDS core");)
|
||||
uds_cs = 1'h1;
|
||||
muxed_rdata_new = uds_read_data;
|
||||
muxed_ready_new = uds_ready;
|
||||
end
|
||||
|
||||
UART_PREFIX: begin
|
||||
`verbose($display("Access to UART core");)
|
||||
uart_cs = 1'h1;
|
||||
muxed_rdata_new = uart_read_data;
|
||||
muxed_ready_new = uart_ready;
|
||||
end
|
||||
|
||||
TOUCH_SENSE_PREFIX: begin
|
||||
`verbose($display("Access to TOUCH_SENSE core");)
|
||||
touch_sense_cs = 1'h1;
|
||||
muxed_rdata_new = touch_sense_read_data;
|
||||
muxed_ready_new = touch_sense_ready;
|
||||
end
|
||||
|
||||
MTA1_PREFIX: begin
|
||||
`verbose($display("Access to MTA1 core");)
|
||||
mta1_cs = 1'h1;
|
||||
muxed_rdata_new = mta1_read_data;
|
||||
muxed_ready_new = mta1_ready;
|
||||
end
|
||||
|
||||
default: begin
|
||||
`verbose($display("UNDEFINED MMIO");)
|
||||
muxed_rdata_new = 32'h00000000;
|
||||
muxed_ready_new = 1'h1;
|
||||
end
|
||||
endcase // case (core_prefix)
|
||||
end // case: MMIO_PREFIX
|
||||
|
||||
default: begin
|
||||
`verbose($display("UNDEFINED AREA");)
|
||||
muxed_rdata_new = 32'h0;
|
||||
muxed_ready_new = 1'h1;
|
||||
end
|
||||
endcase // case (area_prefix)
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // application_fpga
|
||||
|
||||
//======================================================================
|
||||
// EOF application_fpga.v
|
||||
//======================================================================
|
26
hw/application_fpga/tools/makehex/makehex.py
Normal file
26
hw/application_fpga/tools/makehex/makehex.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
|
||||
from sys import argv
|
||||
|
||||
binfile = argv[1]
|
||||
nwords = int(argv[2])
|
||||
|
||||
with open(binfile, "rb") as f:
|
||||
bindata = f.read()
|
||||
|
||||
assert len(bindata) < 4*nwords
|
||||
assert len(bindata) % 4 == 0
|
||||
|
||||
for i in range(nwords):
|
||||
if i < len(bindata) // 4:
|
||||
w = bindata[4*i : 4*i+4]
|
||||
print("%02x%02x%02x%02x" % (w[3], w[2], w[1], w[0]))
|
||||
else:
|
||||
print("0")
|
8
hw/application_fpga/tools/tpt/README.md
Normal file
8
hw/application_fpga/tools/tpt/README.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Tillitis Key Provisioning Tool
|
||||
|
||||
## Introduction
|
||||
Tillis Key Provisioning Tool (tpt) is a program for generating the 32 byte Unique Device Secret (UDS). The tool will also generate the 8 byte Unique Device Identity. Both the UDS and the UDI are injected into the FPGA bitstream file during build.
|
||||
|
||||
The UDS is generated using HKDF (RFC 5869), and the user is expected to supply a secret as part of the input to the HKDF Extract operation. The Input Keying Material is generated by extracting 256 bytes using the Python secrets module.
|
||||
|
||||
The tool uses [python-hkdf](https://github.com/casebeer/python-hkdf).
|
0
hw/application_fpga/tools/tpt/__init__.py
Normal file
0
hw/application_fpga/tools/tpt/__init__.py
Normal file
95
hw/application_fpga/tools/tpt/hkdf.py
Normal file
95
hw/application_fpga/tools/tpt/hkdf.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
# Copyright (c) 2012 Christopher H. Casebeer. All rights reserved.
|
||||
# SPDX-License-Identifier: BSD-2
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from __future__ import division
|
||||
|
||||
import hmac
|
||||
import hashlib
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
buffer = lambda x: x
|
||||
|
||||
def hkdf_extract(salt, input_key_material, hash=hashlib.sha512):
|
||||
'''
|
||||
Extract a pseudorandom key suitable for use with hkdf_expand
|
||||
from the input_key_material and a salt using HMAC with the
|
||||
provided hash (default SHA-512).
|
||||
|
||||
salt should be a random, application-specific byte string. If
|
||||
salt is None or the empty string, an all-zeros string of the same
|
||||
length as the hash's block size will be used instead per the RFC.
|
||||
|
||||
See the HKDF draft RFC and paper for usage notes.
|
||||
'''
|
||||
hash_len = hash().digest_size
|
||||
if salt == None or len(salt) == 0:
|
||||
salt = bytearray((0,) * hash_len)
|
||||
return hmac.new(bytes(salt), buffer(input_key_material), hash).digest()
|
||||
|
||||
def hkdf_expand(pseudo_random_key, info=b"", length=32, hash=hashlib.sha512):
|
||||
'''
|
||||
Expand `pseudo_random_key` and `info` into a key of length `bytes` using
|
||||
HKDF's expand function based on HMAC with the provided hash (default
|
||||
SHA-512). See the HKDF draft RFC and paper for usage notes.
|
||||
'''
|
||||
hash_len = hash().digest_size
|
||||
length = int(length)
|
||||
if length > 255 * hash_len:
|
||||
raise Exception("Cannot expand to more than 255 * %d = %d bytes using the specified hash function" %\
|
||||
(hash_len, 255 * hash_len))
|
||||
blocks_needed = length // hash_len + (0 if length % hash_len == 0 else 1) # ceil
|
||||
okm = b""
|
||||
output_block = b""
|
||||
for counter in range(blocks_needed):
|
||||
output_block = hmac.new(pseudo_random_key, buffer(output_block + info + bytearray((counter + 1,))),\
|
||||
hash).digest()
|
||||
okm += output_block
|
||||
return okm[:length]
|
||||
|
||||
class Hkdf(object):
|
||||
'''
|
||||
Wrapper class for HKDF extract and expand functions
|
||||
'''
|
||||
def __init__(self, salt, input_key_material, hash=hashlib.sha256):
|
||||
'''
|
||||
Extract a pseudorandom key from `salt` and `input_key_material` arguments.
|
||||
|
||||
See the HKDF draft RFC for guidance on setting these values. The constructor
|
||||
optionally takes a `hash` arugment defining the hash function use,
|
||||
defaulting to hashlib.sha256.
|
||||
'''
|
||||
self._hash = hash
|
||||
self._prk = hkdf_extract(salt, input_key_material, self._hash)
|
||||
def expand(self, info=b"", length=32):
|
||||
'''
|
||||
Generate output key material based on an `info` value
|
||||
|
||||
Arguments:
|
||||
- info - context to generate the OKM
|
||||
- length - length in bytes of the key to generate
|
||||
|
||||
See the HKDF draft RFC for guidance.
|
||||
'''
|
||||
return hkdf_expand(self._prk, info, length, self._hash)
|
129
hw/application_fpga/tools/tpt/tpt.py
Executable file
129
hw/application_fpga/tools/tpt/tpt.py
Executable file
|
@ -0,0 +1,129 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#=======================================================================
|
||||
#
|
||||
# tpt.py
|
||||
# ------
|
||||
# TillitisKey Provisioning Tool.
|
||||
#
|
||||
# The tool use HKDF (RFC5869) to generate the UDS.
|
||||
#
|
||||
# Copyright (C) 2022 - Tillitis AB
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
#=======================================================================
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
from secrets import token_bytes
|
||||
from binascii import unhexlify
|
||||
from hkdf import Hkdf
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------
|
||||
def gen_uds(verbose, arg_uss):
|
||||
if verbose:
|
||||
print("\nGenerating UDS")
|
||||
|
||||
if arg_uss == None:
|
||||
uss = str.encode(input("Enter user supplied secret: "))
|
||||
else:
|
||||
uss = str.encode(arg_uss)
|
||||
|
||||
ikm = token_bytes(256)
|
||||
my_hkdf = Hkdf(uss, ikm)
|
||||
uds = my_hkdf.expand(b"TillitisKey UDS", 32)
|
||||
uds_hex = uds.hex()
|
||||
|
||||
if verbose:
|
||||
print("\nGenerated UDS:")
|
||||
print(uds_hex, "\n")
|
||||
|
||||
return uds_hex
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------
|
||||
def save_uds(verbose, uds):
|
||||
if verbose:
|
||||
print("Writing uds.hex")
|
||||
|
||||
with open ("uds.hex", 'w', encoding = 'utf-8') as uds_file:
|
||||
for i in range(8):
|
||||
uds_file.write(uds[(i*8) : (i*8 + 8)]+"\n")
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------
|
||||
def gen_udi(verbose, pid, vid, rev, serial):
|
||||
if verbose:
|
||||
print("Generating UDI")
|
||||
|
||||
if vid == None:
|
||||
vid = int(input("Enter Vendor ID (0 - 65535): "))
|
||||
|
||||
if pid == None:
|
||||
pid = int(input("Enter Product ID (0 - 255): "))
|
||||
|
||||
if rev == None:
|
||||
rev = int(input("Enter revision (0 - 15): "))
|
||||
|
||||
if serial == None:
|
||||
serial = int(input("Enter serial number (0 - (2**32 -1)): "))
|
||||
|
||||
assert vid < 65536
|
||||
assert pid < 256
|
||||
assert rev < 16
|
||||
assert serial < 2**32
|
||||
|
||||
udi_hex = ("0%04x%02x%1x%08x" % (vid, pid, rev, serial))
|
||||
|
||||
if verbose:
|
||||
print("\nGenerated UDI:")
|
||||
print(udi_hex, "\n")
|
||||
|
||||
return udi_hex
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------
|
||||
def save_udi(verbose, udi):
|
||||
if verbose:
|
||||
print("Writing udi.hex")
|
||||
|
||||
with open ("udi.hex", 'w', encoding = 'utf-8') as udi_file:
|
||||
udi_file.write(udi[0 : 8] + "\n")
|
||||
udi_file.write(udi[8 : 16] + "\n")
|
||||
|
||||
def enc_str(b):
|
||||
return bytestring.decode(sys.getfilesystemencoding())
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-v", "--verbose", help="Verbose operation", action="store_true")
|
||||
parser.add_argument("--uss", help="User supplied secret", type=str)
|
||||
parser.add_argument("--vid", help="Vendor id (0 - 65535)", type=int)
|
||||
parser.add_argument("--pid", help="Product id (0 - 2555", type=int)
|
||||
parser.add_argument("--rev", help="Revision number (0 - 15)", type=int)
|
||||
parser.add_argument("--serial", help="Serial number (0 - (2**31 - 1))", type=int)
|
||||
args = parser.parse_args()
|
||||
|
||||
print(args)
|
||||
|
||||
if args.verbose:
|
||||
print("TillitisKey Provisining Tool (TPT)")
|
||||
|
||||
uds = gen_uds(args.verbose, args.uss)
|
||||
save_uds(args.verbose, uds)
|
||||
|
||||
udi = gen_udi(args.verbose, args.pid, args.vid, args.rev, args.serial)
|
||||
save_udi(args.verbose, udi)
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------
|
||||
if __name__=="__main__":
|
||||
sys.exit(main())
|
83
hw/boards/KiCad-RP Pico/Install instructions.md
Normal file
83
hw/boards/KiCad-RP Pico/Install instructions.md
Normal file
|
@ -0,0 +1,83 @@
|
|||
# Install instructions
|
||||
|
||||
## 1. Copy the files locally
|
||||
|
||||
Copy the `RP-Pico Libraries` folder wherever you like on your computer.
|
||||
|
||||
## 2. Install the Raspberry Pi Pico board schema symbol
|
||||
|
||||
Use the `KiCad | Preferences | Manage Symbol Libraries...` command to manage the symbol library:
|
||||
|
||||

|
||||
|
||||
then select the global tab and click on the folder button:
|
||||
|
||||

|
||||
|
||||
navigate to the `RP-Pico Libraries` folder, select the `MCU_RaspberryPi_and_Boards.kicad_sym` file and open it:
|
||||
|
||||

|
||||
|
||||
et voilà, the first step is completed:
|
||||
|
||||

|
||||
|
||||
You can now close the symbol libraries manager window.
|
||||
|
||||
## 3. Install the Raspberry Pi Pico board footprint
|
||||
|
||||
You can use a similar approach to add the footprint to the footprint libraries manager, but I've found some issues that I've solved using the footprint editor, so here are the steps I suggest you to follow:
|
||||
|
||||
Open the footprint editor
|
||||
|
||||

|
||||
|
||||
wait for the footprints to load... then use the `File | Add Library` command:
|
||||
|
||||

|
||||
|
||||
confirm the `Global` choice:
|
||||
|
||||

|
||||
|
||||
and select the `MCU_RaspberriPi_and_Boards.pretty` folder (yes, the folder represent a footprint library on KiCad):
|
||||
|
||||

|
||||
|
||||
Now the library is installed on KiCad with the Raspberry Pi Pico footprint (double click on it to see it on the editor pane):
|
||||
|
||||

|
||||
|
||||
Don't close the windows as the next step start from here.
|
||||
|
||||
## 4. Install the Raspberry Pi Pico board footprint 3D visual
|
||||
|
||||
If not already open, open the the footprint editor
|
||||
|
||||

|
||||
|
||||
double click on the `RPi_Pico_SMD_TH` footprint from the `MCU_RaspberriPi_and_Boards` library and then click on the `Footprint properties` icon:
|
||||
|
||||

|
||||
|
||||
In the footprint properties window, first select the `3D Settings` tab. Please note that the preview shows only the PCB board with the footprint added on step 3, without any 3D representation of the Raspberry Pi Pico board. Now click on the folder icon to add the 3D model:
|
||||
|
||||

|
||||
|
||||
Navigate to the `RP-Pico Libraries` folder, select the `Pico.wrl` file and wait until the model is shown in the right panel, then confirm with OK:
|
||||
|
||||

|
||||
|
||||
The model is already scaled and translated to match the footprint:
|
||||
|
||||

|
||||
|
||||
now close the `Footprint Properties` window, and the `Footprint Editor`, obviously saving the changes.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Now that you've installed the schema and footprint and added the 3D model to the footprint, you can use the Raspberry Pi Pico board on your KiCad projects.
|
||||
|
||||
I've also added a test KiCad Project on the `Test` folder, that you can use to see an example of it.
|
||||
|
||||
Have fun!
|
27
hw/boards/KiCad-RP Pico/LICENSE
Normal file
27
hw/boards/KiCad-RP Pico/LICENSE
Normal file
|
@ -0,0 +1,27 @@
|
|||
### TPCWare KiCad Library License
|
||||
|
||||
The TPCWare KiCad Library is licensed under the [Creative Commons CC-BY-SA 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/legalcode), with the following exception:
|
||||
|
||||
---------
|
||||
|
||||
_To the extent that the creation of electronic designs that use 'Licensed Material' can be considered to be 'Adapted Material', then the copyright holder waives article 3 of the license with respect to these designs and any generated files which use data provided as part of the 'Licensed Material'._
|
||||
|
||||
---------
|
||||
|
||||
|
||||
**What does this mean?**
|
||||
|
||||
TPCWare KiCad Library is licensed in such a way to ensure free use of library data for commercial, closed, and non-commercial projects without restriction. TPCWare Corporation does not wish to exert any control over designs produced using the library data, or force users to reveal proprietary information contained in their designs. Neither do we wish to force users to attribute the TPCWare KiCad Library _within their design_.
|
||||
|
||||
Use of the library data in a project does not (by itself) require that the design or any files generated from the design are licensed under the CC-BY-SA 4.0 License. You are free to use the library data in your own projects without the obligation to share your project files under this or any other license agreement.
|
||||
|
||||
However, if you wish to redistribute the TPCWare KiCad Library, or parts thereof (including in modified form) as a collection then the exception above does not apply. Redistributed library collections must be shared under the same license agreement. Under these circumstances, the libraries must also retain attribution information, including the license documents which are distributed with the library files.
|
||||
|
||||
----------------------
|
||||
|
||||
|
||||
**Disclaimer of Warranties and Limitation of Liability.**
|
||||
|
||||
a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
|
||||
b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
|
||||
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
|
44
hw/boards/KiCad-RP Pico/README.md
Normal file
44
hw/boards/KiCad-RP Pico/README.md
Normal file
|
@ -0,0 +1,44 @@
|
|||
# KiCad-RP-Pico
|
||||
A simple repository of files needed to add a 3D footprint of the Raspberry Pi Pico board to KiCad.
|
||||
|
||||

|
||||
|
||||
## Schematic and footprint
|
||||
I've started from the schematics and footprint files available on the [HeadBoffin RP_Silicon_KiCad GitHub project](https://github.com/HeadBoffin/RP_Silicon_KiCad). Because there are some errors in the readme file on how and where we can get those files from the Raspberry Pi web site, I've copied the needed files here, on the `RP-Pico Libraries` folder. Follow the [install instructions](Install%20instructions.md) to add the Raspberry Pi Pico board schema and footprint to a KiCad project:
|
||||
|
||||

|
||||
|
||||
## 3D Visual
|
||||
Elas, with the files found in the [HeadBoffin project](https://github.com/HeadBoffin/RP_Silicon_KiCad) no visual footprint is available, as we can see on the 3D viewer:
|
||||
|
||||

|
||||
|
||||
So I decided to create one, using the mechanical specification from the [Raspberry Pi Pico datasheet](https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf):
|
||||
|
||||

|
||||
|
||||
I've used SketchUp to create the 3D model:
|
||||
|
||||

|
||||
|
||||
and I used the native Sketchup export function (no plugin needed) to create the VRLM file `Pico.wrl` that I've also added an the `RP-Pico Libraries` folder, as the VRLM format is one of the 3D model format that KiCad allow to use for the visual representation of a CPB footprint.
|
||||
|
||||
After adding it to the Raspberry Pi Pico KiCad footprint library, we can finally see the visual representation of the Raspberry Pi Pico board:
|
||||
|
||||

|
||||
|
||||
Please note that the castellated pins of the Pico board allow it to be usable as a surface mount module. That's way you see the board simply placed on top of the PCB board.
|
||||
|
||||
## Install 3D visual
|
||||
|
||||
Please note that adding the visual file to the footprint make the use of KiCad very slow when showing the 3D viewer for the first time. On my old laptop it takes 30s to show, but only 3s to reopen it. The good news are that you can disable it while working at your project and enable it when you want a nice 3D representation of your work.
|
||||
|
||||
To install and enable/disable it follow the [install instructions](Install%20instructions.md).
|
||||
|
||||
## Test project
|
||||
|
||||
I've created a test project where you can find a simple usage example. The first image of this readme shows the result.
|
||||
|
||||
## License
|
||||
Please read the [License](LICENSE) where is stated that this work is free to use.
|
||||
A tweet with an image of your Raspberry Pi Pico project with a link this project and me (@tpcware) would be greatly appreciated.
|
|
@ -0,0 +1,201 @@
|
|||
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
|
||||
(symbol "Pico" (in_bom yes) (on_board yes)
|
||||
(property "Reference" "U" (id 0) (at -13.97 27.94 0)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
(property "Value" "Pico" (id 1) (at 0 19.05 0)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
(property "Footprint" "RPi_Pico:RPi_Pico_SMD_TH" (id 2) (at 0 0 90)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "" (id 3) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(symbol "Pico_0_0"
|
||||
(text "Raspberry Pi Pico" (at 0 21.59 0)
|
||||
(effects (font (size 1.27 1.27)))
|
||||
)
|
||||
)
|
||||
(symbol "Pico_0_1"
|
||||
(rectangle (start -15.24 26.67) (end 15.24 -26.67)
|
||||
(stroke (width 0) (type default) (color 0 0 0 0))
|
||||
(fill (type background))
|
||||
)
|
||||
)
|
||||
(symbol "Pico_1_1"
|
||||
(pin bidirectional line (at -17.78 24.13 0) (length 2.54)
|
||||
(name "GPIO0" (effects (font (size 1.27 1.27))))
|
||||
(number "1" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 1.27 0) (length 2.54)
|
||||
(name "GPIO7" (effects (font (size 1.27 1.27))))
|
||||
(number "10" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 -1.27 0) (length 2.54)
|
||||
(name "GPIO8" (effects (font (size 1.27 1.27))))
|
||||
(number "11" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 -3.81 0) (length 2.54)
|
||||
(name "GPIO9" (effects (font (size 1.27 1.27))))
|
||||
(number "12" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at -17.78 -6.35 0) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "13" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 -8.89 0) (length 2.54)
|
||||
(name "GPIO10" (effects (font (size 1.27 1.27))))
|
||||
(number "14" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 -11.43 0) (length 2.54)
|
||||
(name "GPIO11" (effects (font (size 1.27 1.27))))
|
||||
(number "15" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 -13.97 0) (length 2.54)
|
||||
(name "GPIO12" (effects (font (size 1.27 1.27))))
|
||||
(number "16" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 -16.51 0) (length 2.54)
|
||||
(name "GPIO13" (effects (font (size 1.27 1.27))))
|
||||
(number "17" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at -17.78 -19.05 0) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "18" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 -21.59 0) (length 2.54)
|
||||
(name "GPIO14" (effects (font (size 1.27 1.27))))
|
||||
(number "19" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 21.59 0) (length 2.54)
|
||||
(name "GPIO1" (effects (font (size 1.27 1.27))))
|
||||
(number "2" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 -24.13 0) (length 2.54)
|
||||
(name "GPIO15" (effects (font (size 1.27 1.27))))
|
||||
(number "20" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 -24.13 180) (length 2.54)
|
||||
(name "GPIO16" (effects (font (size 1.27 1.27))))
|
||||
(number "21" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 -21.59 180) (length 2.54)
|
||||
(name "GPIO17" (effects (font (size 1.27 1.27))))
|
||||
(number "22" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at 17.78 -19.05 180) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "23" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 -16.51 180) (length 2.54)
|
||||
(name "GPIO18" (effects (font (size 1.27 1.27))))
|
||||
(number "24" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 -13.97 180) (length 2.54)
|
||||
(name "GPIO19" (effects (font (size 1.27 1.27))))
|
||||
(number "25" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 -11.43 180) (length 2.54)
|
||||
(name "GPIO20" (effects (font (size 1.27 1.27))))
|
||||
(number "26" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 -8.89 180) (length 2.54)
|
||||
(name "GPIO21" (effects (font (size 1.27 1.27))))
|
||||
(number "27" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at 17.78 -6.35 180) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "28" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 -3.81 180) (length 2.54)
|
||||
(name "GPIO22" (effects (font (size 1.27 1.27))))
|
||||
(number "29" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at -17.78 19.05 0) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "3" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin input line (at 17.78 -1.27 180) (length 2.54)
|
||||
(name "RUN" (effects (font (size 1.27 1.27))))
|
||||
(number "30" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 1.27 180) (length 2.54)
|
||||
(name "GPIO26_ADC0" (effects (font (size 1.27 1.27))))
|
||||
(number "31" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 3.81 180) (length 2.54)
|
||||
(name "GPIO27_ADC1" (effects (font (size 1.27 1.27))))
|
||||
(number "32" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at 17.78 6.35 180) (length 2.54)
|
||||
(name "AGND" (effects (font (size 1.27 1.27))))
|
||||
(number "33" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 8.89 180) (length 2.54)
|
||||
(name "GPIO28_ADC2" (effects (font (size 1.27 1.27))))
|
||||
(number "34" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at 17.78 11.43 180) (length 2.54)
|
||||
(name "ADC_VREF" (effects (font (size 1.27 1.27))))
|
||||
(number "35" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at 17.78 13.97 180) (length 2.54)
|
||||
(name "3V3" (effects (font (size 1.27 1.27))))
|
||||
(number "36" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin input line (at 17.78 16.51 180) (length 2.54)
|
||||
(name "3V3_EN" (effects (font (size 1.27 1.27))))
|
||||
(number "37" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 17.78 19.05 180) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "38" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at 17.78 21.59 180) (length 2.54)
|
||||
(name "VSYS" (effects (font (size 1.27 1.27))))
|
||||
(number "39" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 16.51 0) (length 2.54)
|
||||
(name "GPIO2" (effects (font (size 1.27 1.27))))
|
||||
(number "4" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at 17.78 24.13 180) (length 2.54)
|
||||
(name "VBUS" (effects (font (size 1.27 1.27))))
|
||||
(number "40" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin input line (at -2.54 -29.21 90) (length 2.54)
|
||||
(name "SWCLK" (effects (font (size 1.27 1.27))))
|
||||
(number "41" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at 0 -29.21 90) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "42" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at 2.54 -29.21 90) (length 2.54)
|
||||
(name "SWDIO" (effects (font (size 1.27 1.27))))
|
||||
(number "43" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 13.97 0) (length 2.54)
|
||||
(name "GPIO3" (effects (font (size 1.27 1.27))))
|
||||
(number "5" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 11.43 0) (length 2.54)
|
||||
(name "GPIO4" (effects (font (size 1.27 1.27))))
|
||||
(number "6" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 8.89 0) (length 2.54)
|
||||
(name "GPIO5" (effects (font (size 1.27 1.27))))
|
||||
(number "7" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin power_in line (at -17.78 6.35 0) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "8" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
(pin bidirectional line (at -17.78 3.81 0) (length 2.54)
|
||||
(name "GPIO6" (effects (font (size 1.27 1.27))))
|
||||
(number "9" (effects (font (size 1.27 1.27))))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
|
@ -0,0 +1,153 @@
|
|||
(footprint "RPi_Pico_SMD" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 6224DF39)
|
||||
(descr "Through hole straight pin header, 2x20, 2.54mm pitch, double rows")
|
||||
(tags "Through hole pin header THT 2x20 2.54mm double row")
|
||||
(attr through_hole)
|
||||
(fp_text reference "REF**" (at 0 0) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 96315415-cfed-47d2-b3dd-d782358bd0df)
|
||||
)
|
||||
(fp_text value "RPi_Pico_SMD" (at 0 2.159) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 46cbe85d-ff47-428e-b187-4ebd50a66e0c)
|
||||
)
|
||||
(fp_text user "Copper Keepouts shown on Dwgs layer" (at 0.1 -30.2) (layer "Cmts.User")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 66ca01b3-51ff-4294-9b77-4492e98f6aec)
|
||||
)
|
||||
(fp_text user "${REFERENCE}" (at 0 0 180) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 83184391-76ed-44f0-8cd0-01f89f157bdb)
|
||||
)
|
||||
(fp_line (start 10.5 4.9) (end 10.5 5.3) (layer "F.SilkS") (width 0.12) (tstamp 099473f1-6598-46ff-a50f-4c520832170d))
|
||||
(fp_line (start -10.5 -23.1) (end -10.5 -22.7) (layer "F.SilkS") (width 0.12) (tstamp 0c5dddf1-38df-43d2-b49c-e7b691dab0ab))
|
||||
(fp_line (start -10.5 -20.5) (end -10.5 -20.1) (layer "F.SilkS") (width 0.12) (tstamp 0ce1dd44-f307-4f98-9f0d-478fd87daa64))
|
||||
(fp_line (start 10.5 10) (end 10.5 10.4) (layer "F.SilkS") (width 0.12) (tstamp 15699041-ed40-45ee-87d8-f5e206a88536))
|
||||
(fp_line (start -3.7 25.5) (end -10.5 25.5) (layer "F.SilkS") (width 0.12) (tstamp 1855ca44-ab48-4b76-a210-97fc81d916c4))
|
||||
(fp_line (start 10.5 -0.2) (end 10.5 0.2) (layer "F.SilkS") (width 0.12) (tstamp 1876c30c-72b2-4a8d-9f32-bf8b213530b4))
|
||||
(fp_line (start 10.5 22.7) (end 10.5 23.1) (layer "F.SilkS") (width 0.12) (tstamp 199124ca-dd64-45cf-a063-97cc545cbea7))
|
||||
(fp_line (start 10.5 -23.1) (end 10.5 -22.7) (layer "F.SilkS") (width 0.12) (tstamp 1bd80cf9-f42a-4aee-a408-9dbf4e81e625))
|
||||
(fp_line (start -7.493 -22.833) (end -7.493 -25.5) (layer "F.SilkS") (width 0.12) (tstamp 254f7cc6-cee1-44ca-9afe-939b318201aa))
|
||||
(fp_line (start 10.5 -5.3) (end 10.5 -4.9) (layer "F.SilkS") (width 0.12) (tstamp 26a22c19-4cc5-4237-9651-0edc4f854154))
|
||||
(fp_line (start -10.5 -25.5) (end 10.5 -25.5) (layer "F.SilkS") (width 0.12) (tstamp 3457afc5-3e4f-4220-81d1-b079f653a722))
|
||||
(fp_line (start -10.5 20.1) (end -10.5 20.5) (layer "F.SilkS") (width 0.12) (tstamp 3b65c51e-c243-447e-bee9-832d94c1630e))
|
||||
(fp_line (start -10.5 -2.7) (end -10.5 -2.3) (layer "F.SilkS") (width 0.12) (tstamp 3bbbbb7d-391c-4fee-ac81-3c47878edc38))
|
||||
(fp_line (start -10.5 22.7) (end -10.5 23.1) (layer "F.SilkS") (width 0.12) (tstamp 402c62e6-8d8e-473a-a0cf-2b86e4908cd7))
|
||||
(fp_line (start -10.5 -15.4) (end -10.5 -15) (layer "F.SilkS") (width 0.12) (tstamp 4970ec6e-3725-4619-b57d-dc2c2cb86ed0))
|
||||
(fp_line (start -10.5 -5.3) (end -10.5 -4.9) (layer "F.SilkS") (width 0.12) (tstamp 4a53fa56-d65b-42a4-a4be-8f49c4c015bb))
|
||||
(fp_line (start 10.5 -2.7) (end 10.5 -2.3) (layer "F.SilkS") (width 0.12) (tstamp 4bbde53d-6894-4e18-9480-84a6a26d5f6b))
|
||||
(fp_line (start 10.5 25.5) (end 3.7 25.5) (layer "F.SilkS") (width 0.12) (tstamp 54ed3ee1-891b-418e-ab9c-6a18747d7388))
|
||||
(fp_line (start 10.5 -15.4) (end 10.5 -15) (layer "F.SilkS") (width 0.12) (tstamp 57f248a7-365e-4c42-b80d-5a7d1f9dfaf3))
|
||||
(fp_line (start -10.5 7.4) (end -10.5 7.8) (layer "F.SilkS") (width 0.12) (tstamp 5bab6a37-1fdf-4cf8-b571-44c962ed86e9))
|
||||
(fp_line (start -10.5 -22.833) (end -7.493 -22.833) (layer "F.SilkS") (width 0.12) (tstamp 5f48b0f2-82cf-40ce-afac-440f97643c36))
|
||||
(fp_line (start -10.5 -7.8) (end -10.5 -7.4) (layer "F.SilkS") (width 0.12) (tstamp 6150c02b-beb5-4af1-951e-3666a285a6ea))
|
||||
(fp_line (start -10.5 4.9) (end -10.5 5.3) (layer "F.SilkS") (width 0.12) (tstamp 706c1cb9-5d96-4282-9efc-6147f0125147))
|
||||
(fp_line (start -1.5 25.5) (end -1.1 25.5) (layer "F.SilkS") (width 0.12) (tstamp 749d9ed0-2ff2-4b55-abc5-f7231ec3aa28))
|
||||
(fp_line (start -10.5 -12.9) (end -10.5 -12.5) (layer "F.SilkS") (width 0.12) (tstamp 755f94aa-38f0-4a64-a7c7-6c71cb18cddf))
|
||||
(fp_line (start 10.5 -20.5) (end 10.5 -20.1) (layer "F.SilkS") (width 0.12) (tstamp 80095e91-6317-4cfb-9aea-884c9a1accc5))
|
||||
(fp_line (start -10.5 15.1) (end -10.5 15.5) (layer "F.SilkS") (width 0.12) (tstamp 88deea08-baa5-4041-beb7-01c299cf00e6))
|
||||
(fp_line (start 1.1 25.5) (end 1.5 25.5) (layer "F.SilkS") (width 0.12) (tstamp 8a8c373f-9bc3-4cf7-8f41-4802da916698))
|
||||
(fp_line (start 10.5 -12.9) (end 10.5 -12.5) (layer "F.SilkS") (width 0.12) (tstamp 9112ddd5-10d5-48b8-954f-f1d5adcacbd9))
|
||||
(fp_line (start -10.5 10) (end -10.5 10.4) (layer "F.SilkS") (width 0.12) (tstamp 92f063a3-7cce-4a96-8a3a-cf5767f700c6))
|
||||
(fp_line (start 10.5 2.3) (end 10.5 2.7) (layer "F.SilkS") (width 0.12) (tstamp 968a6172-7a4e-40ab-a78a-e4d03671e136))
|
||||
(fp_line (start -10.5 -10.4) (end -10.5 -10) (layer "F.SilkS") (width 0.12) (tstamp 9c2999b2-1cf1-4204-9d23-243401b77aa3))
|
||||
(fp_line (start -10.5 -0.2) (end -10.5 0.2) (layer "F.SilkS") (width 0.12) (tstamp 9ed09117-33cf-45a3-85a7-2606522feaf8))
|
||||
(fp_line (start -10.5 17.6) (end -10.5 18) (layer "F.SilkS") (width 0.12) (tstamp a177c3b4-b04c-490e-b3fe-d3d4d7aa24a7))
|
||||
(fp_line (start -10.5 12.5) (end -10.5 12.9) (layer "F.SilkS") (width 0.12) (tstamp ad4d05f5-6957-42f8-b65c-c657b9a26485))
|
||||
(fp_line (start 10.5 7.4) (end 10.5 7.8) (layer "F.SilkS") (width 0.12) (tstamp af76ce95-feca-41fb-bf31-edaa26d6766a))
|
||||
(fp_line (start 10.5 -10.4) (end 10.5 -10) (layer "F.SilkS") (width 0.12) (tstamp c1b11207-7c0a-49b3-a41d-2fe677d5f3b8))
|
||||
(fp_line (start 10.5 17.6) (end 10.5 18) (layer "F.SilkS") (width 0.12) (tstamp c346b00c-b5e0-4939-beb4-7f48172ef334))
|
||||
(fp_line (start 10.5 -7.8) (end 10.5 -7.4) (layer "F.SilkS") (width 0.12) (tstamp c3d5daf8-d359-42b2-a7c2-0d080ba7e212))
|
||||
(fp_line (start -10.5 -25.5) (end -10.5 -25.2) (layer "F.SilkS") (width 0.12) (tstamp ca56e1ad-54bf-4df5-a4f7-99f5d61d0de9))
|
||||
(fp_line (start 10.5 20.1) (end 10.5 20.5) (layer "F.SilkS") (width 0.12) (tstamp ca9b74ce-0dee-401c-9544-f599f4cf538d))
|
||||
(fp_line (start 10.5 12.5) (end 10.5 12.9) (layer "F.SilkS") (width 0.12) (tstamp d3dd7cdb-b730-487d-804d-99150ba318ef))
|
||||
(fp_line (start 10.5 -18) (end 10.5 -17.6) (layer "F.SilkS") (width 0.12) (tstamp e11ae5a5-aa10-4f10-b346-f16e33c7899a))
|
||||
(fp_line (start -10.5 2.3) (end -10.5 2.7) (layer "F.SilkS") (width 0.12) (tstamp eb391a95-1c1d-4613-b508-c76b8bc13a73))
|
||||
(fp_line (start 10.5 -25.5) (end 10.5 -25.2) (layer "F.SilkS") (width 0.12) (tstamp f23ac723-a36d-491d-9473-7ec0ffed332d))
|
||||
(fp_line (start -10.5 -18) (end -10.5 -17.6) (layer "F.SilkS") (width 0.12) (tstamp f8b47531-6c06-4e54-9fc9-cd9d0f3dd69f))
|
||||
(fp_line (start 10.5 15.1) (end 10.5 15.5) (layer "F.SilkS") (width 0.12) (tstamp fd60415a-f01a-46c5-9369-ea970e435e5b))
|
||||
(fp_poly (pts
|
||||
(xy -1.5 -16.5)
|
||||
(xy -3.5 -16.5)
|
||||
(xy -3.5 -18.5)
|
||||
(xy -1.5 -18.5)
|
||||
) (layer "Dwgs.User") (width 0.1) (fill solid) (tstamp 022502e0-e724-4b75-bc35-3c5984dbeb76))
|
||||
(fp_poly (pts
|
||||
(xy -1.5 -11.5)
|
||||
(xy -3.5 -11.5)
|
||||
(xy -3.5 -13.5)
|
||||
(xy -1.5 -13.5)
|
||||
) (layer "Dwgs.User") (width 0.1) (fill solid) (tstamp 9f969b13-1795-4747-8326-93bdc304ed56))
|
||||
(fp_poly (pts
|
||||
(xy 3.7 -20.2)
|
||||
(xy -3.7 -20.2)
|
||||
(xy -3.7 -24.9)
|
||||
(xy 3.7 -24.9)
|
||||
) (layer "Dwgs.User") (width 0.1) (fill solid) (tstamp b9d4de74-d246-495d-8b63-12ab2133d6d6))
|
||||
(fp_poly (pts
|
||||
(xy -1.5 -14)
|
||||
(xy -3.5 -14)
|
||||
(xy -3.5 -16)
|
||||
(xy -1.5 -16)
|
||||
) (layer "Dwgs.User") (width 0.1) (fill solid) (tstamp d655bb0a-cbf9-4908-ad60-7024ff468fbd))
|
||||
(fp_line (start 11 26) (end -11 26) (layer "F.CrtYd") (width 0.12) (tstamp 5e755161-24a5-4650-a6e3-9836bf074412))
|
||||
(fp_line (start -11 -26) (end 11 -26) (layer "F.CrtYd") (width 0.12) (tstamp 9208ea78-8dde-4b3d-91e9-5755ab5efd9a))
|
||||
(fp_line (start -10.5 -24.2) (end -9.2 -25.5) (layer "F.Fab") (width 0.12) (tstamp 1bf7d0f9-0dcf-4d7c-b58c-318e3dc42bc9))
|
||||
(fp_line (start 10.5 -25.5) (end 10.5 25.5) (layer "F.Fab") (width 0.12) (tstamp 247ebffd-2cb6-4379-ba6e-21861fea3913))
|
||||
(fp_line (start 10.5 25.5) (end -10.5 25.5) (layer "F.Fab") (width 0.12) (tstamp 94d24676-7ae3-483c-8bd6-88d31adf00b4))
|
||||
(fp_line (start -10.5 -25.5) (end 10.5 -25.5) (layer "F.Fab") (width 0.12) (tstamp 966ee9ec-860e-45bb-af89-30bda72b2032))
|
||||
(fp_line (start -10.5 25.5) (end -10.5 -25.5) (layer "F.Fab") (width 0.12) (tstamp e45aa7d8-0254-4176-afd9-766820762e19))
|
||||
(pad "" np_thru_hole oval (at 2.425 -20.97) (size 1.5 1.5) (drill 1.5) (layers *.Cu *.Mask) (tstamp 1861450d-e718-4eee-89be-56d3334bef29))
|
||||
(pad "" np_thru_hole oval (at -2.425 -20.97) (size 1.5 1.5) (drill 1.5) (layers *.Cu *.Mask) (tstamp 1d257dac-277d-4b80-9286-dd0e04ef5f8d))
|
||||
(pad "" np_thru_hole oval (at 2.725 -24) (size 1.8 1.8) (drill 1.8) (layers *.Cu *.Mask) (tstamp 372f7e30-c773-4278-b448-9703d0bbb68a))
|
||||
(pad "" np_thru_hole oval (at -2.725 -24) (size 1.8 1.8) (drill 1.8) (layers F&B.Cu *.Mask) (tstamp baa6854b-78fb-4bdc-8754-979b449b6762))
|
||||
(pad "1" smd rect (at -8.89 -24.13) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 761c8e29-382a-475c-a37a-7201cc9cd0f5))
|
||||
(pad "2" smd rect (at -8.89 -21.59) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp e50c80c5-80c4-46a3-8c1e-c9c3a71a0934))
|
||||
(pad "3" smd rect (at -8.89 -19.05) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 7233cb6b-d8fd-4fcd-9b4f-8b0ed19b1b12))
|
||||
(pad "4" smd rect (at -8.89 -16.51) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp df83f395-2d18-47e2-a370-952ca41c2b3a))
|
||||
(pad "5" smd rect (at -8.89 -13.97) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 653a86ba-a1ae-4175-9d4c-c788087956d0))
|
||||
(pad "6" smd rect (at -8.89 -11.43) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 3ed2c840-383d-4cbd-bc3b-c4ea4c97b333))
|
||||
(pad "7" smd rect (at -8.89 -8.89) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 6a0919c2-460c-4229-b872-14e318e1ba8b))
|
||||
(pad "8" smd rect (at -8.89 -6.35) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp d1c19c11-0a13-4237-b6b4-fb2ef1db7c6d))
|
||||
(pad "9" smd rect (at -8.89 -3.81) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 29cbb0bc-f66b-4d11-80e7-5bb270e42496))
|
||||
(pad "10" smd rect (at -8.89 -1.27) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp c401e9c6-1deb-4979-99be-7c801c952098))
|
||||
(pad "11" smd rect (at -8.89 1.27) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 355ced6c-c08a-4586-9a09-7a9c624536f6))
|
||||
(pad "12" smd rect (at -8.89 3.81) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp c2dd13db-24b6-40f1-b75b-b9ab893d92ea))
|
||||
(pad "13" smd rect (at -8.89 6.35) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp d8200a86-aa75-47a3-ad2a-7f4c9c999a6f))
|
||||
(pad "14" smd rect (at -8.89 8.89) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 465137b4-f6f7-4d51-9b40-b161947d5cc1))
|
||||
(pad "15" smd rect (at -8.89 11.43) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp d1cd5391-31d2-459f-8adb-4ae3f304a833))
|
||||
(pad "16" smd rect (at -8.89 13.97) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 4086cbd7-6ba7-4e63-8da9-17e60627ee17))
|
||||
(pad "17" smd rect (at -8.89 16.51) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp bb8162f0-99c8-4884-be5b-c0d0c7e81ff6))
|
||||
(pad "18" smd rect (at -8.89 19.05) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 91fc5800-6029-46b1-848d-ca0091f97267))
|
||||
(pad "19" smd rect (at -8.89 21.59) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 275b6416-db29-42cc-9307-bf426917c3b4))
|
||||
(pad "20" smd rect (at -8.89 24.13) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 3c22d605-7855-4cc6-8ad2-906cadbd02dc))
|
||||
(pad "21" smd rect (at 8.89 24.13) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 24adc223-60f0-4497-98a3-d664c5a13280))
|
||||
(pad "22" smd rect (at 8.89 21.59) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 13ac70df-e9b9-44e5-96e6-20f0b0dc6a3a))
|
||||
(pad "23" smd rect (at 8.89 19.05) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 278a91dc-d57d-4a5c-a045-34b6bd84131f))
|
||||
(pad "24" smd rect (at 8.89 16.51) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 98966de3-2364-43d8-a2e0-b03bb9487b03))
|
||||
(pad "25" smd rect (at 8.89 13.97) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 4cc0e615-05a0-4f42-a208-4011ba8ef841))
|
||||
(pad "26" smd rect (at 8.89 11.43) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 4641c87c-bffa-41fe-ae77-be3a97a6f797))
|
||||
(pad "27" smd rect (at 8.89 8.89) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp da546d77-4b03-4562-8fc6-837fd68e7691))
|
||||
(pad "28" smd rect (at 8.89 6.35) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp e2fac877-439c-4da0-af2e-5fdc70f85d42))
|
||||
(pad "29" smd rect (at 8.89 3.81) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 2ea8fa6f-efc3-40fe-bcf9-05bfa46ead4f))
|
||||
(pad "30" smd rect (at 8.89 1.27) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 9da1ace0-4181-4f12-80f8-16786a9e5c07))
|
||||
(pad "31" smd rect (at 8.89 -1.27) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 29126f72-63f7-4275-8b12-6b96a71c6f17))
|
||||
(pad "32" smd rect (at 8.89 -3.81) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp af186015-d283-4209-aade-a247e5de01df))
|
||||
(pad "33" smd rect (at 8.89 -6.35) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 8d063f79-9282-4820-bcf4-1ff3c006cf08))
|
||||
(pad "34" smd rect (at 8.89 -8.89) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 0554bea0-89b2-4e25-9ea3-4c73921c94cb))
|
||||
(pad "35" smd rect (at 8.89 -11.43) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 88606262-3ac5-44a1-aacc-18b26cf4d396))
|
||||
(pad "36" smd rect (at 8.89 -13.97) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp cd1cff81-9d8a-4511-96d6-4ddb79484001))
|
||||
(pad "37" smd rect (at 8.89 -16.51) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 22962957-1efd-404d-83db-5b233b6c15b0))
|
||||
(pad "38" smd rect (at 8.89 -19.05) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 8eb98c56-17e4-4de6-a3e3-06dcfa392040))
|
||||
(pad "39" smd rect (at 8.89 -21.59) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp c66a19ed-90c0-4502-ae75-6a4c4ab9f297))
|
||||
(pad "40" smd rect (at 8.89 -24.13) (size 3.5 1.7) (drill (offset 0.9 0)) (layers "F.Cu" "F.Mask") (tstamp bd085057-7c0e-463a-982b-968a2dc1f0f8))
|
||||
(pad "41" smd rect (at -2.54 23.9 90) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp b21299b9-3c4d-43df-b399-7f9b08eb5470))
|
||||
(pad "42" smd rect (at 0 23.9 90) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp 751d823e-1d7b-4501-9658-d06d459b0e16))
|
||||
(pad "43" smd rect (at 2.54 23.9 90) (size 3.5 1.7) (drill (offset -0.9 0)) (layers "F.Cu" "F.Mask") (tstamp aadc3df5-0e2d-4f3d-b72e-6f184da74c89))
|
||||
(model "${KIPRJMOD}/../KiCad-RP Pico/RP-Pico-Libraries/Pico.wrl"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
516771
hw/boards/KiCad-RP Pico/RP-Pico-Libraries/Pico.wrl
Normal file
516771
hw/boards/KiCad-RP Pico/RP-Pico-Libraries/Pico.wrl
Normal file
File diff suppressed because it is too large
Load diff
54
hw/boards/README.md
Normal file
54
hw/boards/README.md
Normal file
|
@ -0,0 +1,54 @@
|
|||
# MTA1-USB PCB designs
|
||||
|
||||
## Boards
|
||||
|
||||
The KiCad board projects all follow this directory structure:
|
||||
|
||||
| Path | Description |
|
||||
| --- | --- |
|
||||
| /project | KiCad 6 project |
|
||||
| /project/gerbers | PCB release files |
|
||||
| /project/test | Scripts / gateware used for production tests |
|
||||
|
||||
### mta1-usb-v1
|
||||
|
||||

|
||||
|
||||
This is the first production version of the MTA1-USB design.
|
||||
|
||||
Main features:
|
||||
* Miniaturized hardware the size of a small USB stick.
|
||||
* The Interface FPGA from the MTA1-USB-DEV design has been replaced with an Interface MCU running a USB-to-Serial converter firmware. This was done to ease development of the FPGA design.
|
||||
* A touch sensor IC is provided instead of the switch for user presence detection.
|
||||
* Test pads are provided on the bottom of the board for programming the SPI flash, and also for measuring extra GPIO pins. The 'MTA1-USB-V1-Programmer' board is designed to support this.
|
||||
|
||||
### mta1-usb-v1-programmer
|
||||
|
||||

|
||||
|
||||
This is a programming jig for the mta1-usb-v1 board.
|
||||
|
||||
### mta1-usb-dev
|
||||
|
||||

|
||||
|
||||
This is the original design, intended as a development platform. It is a larger PCB, that connects to a PC via a USB C cable.
|
||||
|
||||
Main features:
|
||||
* 2 ICE40 FPGAs.
|
||||
* The first ICE40 (Interface FPGA) is connected to a USB C plug, and is loaded with a gateware that contains a soft USB device. This gateware acts as an USB-to-GPIO interface to the second ICE40.
|
||||
* The second ICE40 (application FPGA) is loaded with a RISC-V soft core containing the security firmware. User applications are run on this gateware.
|
||||
* The second ICE40 also has an input button for user presenence detection.
|
||||
* An FTDI module is included for programming both the Application and Interface FPGAs.
|
||||
* Both ICE40s can be configured to boot from included SPI flash memories, NVCM, or be live programmed from the FTDI module.
|
||||
* All GPIO lines between the two FPGAs, as well as all programming signals, are exposed on 0.1" headers for probing.
|
||||
|
||||
## Libraries
|
||||
|
||||
### mta1-library
|
||||
|
||||
This is a shared KiCad library for all boards in the project.
|
||||
|
||||
### KiCad-RP Pico
|
||||
|
||||
This is a KiCad library for the Raspberry Pi Pico symbol and footprint. It was extracted from the [Kicad-RP-Pico](https://github.com/ncarandini/KiCad-RP-Pico) project. It is licensed under the [Creative Commons CC-BY-SA 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/legalcode), with an exception exempting waving any control of derived works.
|
34
hw/boards/mta1-library/CERN_OHL_S_drawing_sheet.kicad_wks
Normal file
34
hw/boards/mta1-library/CERN_OHL_S_drawing_sheet.kicad_wks
Normal file
|
@ -0,0 +1,34 @@
|
|||
(kicad_wks (version 20210606) (generator pl_editor)
|
||||
(setup (textsize 1.5 1.5)(linewidth 0.15)(textlinewidth 0.15)
|
||||
(left_margin 10)(right_margin 10)(top_margin 10)(bottom_margin 10))
|
||||
(rect (name "") (start 110 60) (end 2 2) (comment "rect around the title block")
|
||||
)
|
||||
(rect (name "") (start 0 0 ltcorner) (end 0 0) (repeat 2) (incrx 2) (incry 2))
|
||||
(line (name "") (start 50 2 ltcorner) (end 50 0 ltcorner) (repeat 30) (incrx 50))
|
||||
(tbtext "1" (name "") (pos 25 1 ltcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50))
|
||||
(line (name "") (start 50 2 lbcorner) (end 50 0 lbcorner) (repeat 30) (incrx 50))
|
||||
(tbtext "1" (name "") (pos 25 1 lbcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50))
|
||||
(line (name "") (start 0 50 ltcorner) (end 2 50 ltcorner) (repeat 30) (incry 50))
|
||||
(tbtext "A" (name "") (pos 1 25 ltcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50))
|
||||
(line (name "") (start 0 50 rtcorner) (end 2 50 rtcorner) (repeat 30) (incry 50))
|
||||
(tbtext "A" (name "") (pos 1 25 rtcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50))
|
||||
(tbtext "Date: ${ISSUE_DATE}" (name "") (pos 87 6.9))
|
||||
(line (name "") (start 110 5.5) (end 2 5.5))
|
||||
(tbtext "${KICAD_VERSION}" (name "") (pos 109 4.1) (comment "Kicad version")
|
||||
)
|
||||
(line (name "") (start 110 8.5) (end 2 8.5))
|
||||
(tbtext "Rev: ${REVISION}" (name "") (pos 24 6.9) (font bold))
|
||||
(tbtext "Size: ${PAPER}" (name "") (pos 109 6.9) (comment "Paper format name")
|
||||
)
|
||||
(tbtext "Id: ${#}/${##}" (name "") (pos 24 4.1) (comment "Sheet id")
|
||||
)
|
||||
(line (name "") (start 110 12.5) (end 2 12.5))
|
||||
(tbtext "Title: ${TITLE}" (name "") (pos 109 10.7) (font (size 2 2) bold italic))
|
||||
(tbtext "File: ${FILENAME}" (name "") (pos 109 14.3))
|
||||
(line (name "") (start 110 18.5) (end 2 18.5))
|
||||
(tbtext "Sheet: ${SHEETNAME}" (name "") (pos 109 17))
|
||||
(line (name "") (start 90 8.5) (end 90 5.5))
|
||||
(line (name "") (start 26 8.5) (end 26 2))
|
||||
(tbtext "This document describes Open Hardware and is licensed under the CERN-OHL-S v2.\n\nYou may redistribute and modify this source and make products using it under\nthe terms of the CERN-OHL-S v2 (https://ohwr.org/cern_ohl_s_v2.txt).\n\nThis source is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING\nOF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE.\nPlease see the CERN-OHL-S v2 for applicable conditions." (name "") (pos 107.729 33.0022))
|
||||
(tbtext "Copyright ${COMPANY} ${COMMENT1}" (name "") (pos 107.729 53.3222) (font (size 2.5 2.5) bold))
|
||||
)
|
15
hw/boards/mta1-library/mta1.dcm
Normal file
15
hw/boards/mta1-library/mta1.dcm
Normal file
|
@ -0,0 +1,15 @@
|
|||
EESchema-DOCLIB Version 2.0
|
||||
#
|
||||
$CMP ICE40UP5K-SG48ITR
|
||||
D iCE40 UltraPlus FPGA, 5280 LUTs, 1.2V, 48-pin QFN
|
||||
K FPGA programmable logic
|
||||
F http://www.latticesemi.com/Products/FPGAandCPLD/iCE40Ultra
|
||||
$ENDCMP
|
||||
#
|
||||
$CMP W25Q80DVSNIG
|
||||
D 32Mb Serial Flash Memory, Standard/Dual/Quad SPI, SOIC-8
|
||||
K flash memory SPI
|
||||
F https://www.winbond.com/resource-files/w25q80dv_revg_07212015.pdf
|
||||
$ENDCMP
|
||||
#
|
||||
#End Doc Library
|
1615
hw/boards/mta1-library/mta1.kicad_sym
Normal file
1615
hw/boards/mta1-library/mta1.kicad_sym
Normal file
File diff suppressed because it is too large
Load diff
61
hw/boards/mta1-library/mta1.pretty/0402rgb-1010.kicad_mod
Normal file
61
hw/boards/mta1-library/mta1.pretty/0402rgb-1010.kicad_mod
Normal file
|
@ -0,0 +1,61 @@
|
|||
(footprint "0402rgb-1010" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 616EE650)
|
||||
(attr smd)
|
||||
(fp_text reference "D" (at 0 0) (layer "F.Fab")
|
||||
(effects (font (size 0.5 0.5) (thickness 0.075)))
|
||||
(tstamp 6eaf44a5-2bb8-4e84-ae85-e082a57042dd)
|
||||
)
|
||||
(fp_text value "0402rgb-1010" (at 0.0635 -1.54178) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 4e647fa9-4baf-493a-891e-373b7bb90db1)
|
||||
)
|
||||
(fp_poly (pts
|
||||
(xy -0.6096 -0.60198)
|
||||
(xy -0.29972 -0.60198)
|
||||
(xy -0.29972 -0.25146)
|
||||
(xy -0.6096 -0.25146)
|
||||
(xy -0.6096 -0.45212)
|
||||
) (layer "F.Paste") (width 0.01) (fill solid) (tstamp 8cd8d6bd-0601-49fc-9009-a437af9b27c1))
|
||||
(fp_poly (pts
|
||||
(xy 0.2921 0.25146)
|
||||
(xy 0.60198 0.25146)
|
||||
(xy 0.60198 0.60198)
|
||||
(xy 0.2921 0.60198)
|
||||
(xy 0.2921 0.40132)
|
||||
) (layer "F.Paste") (width 0.01) (fill solid) (tstamp c0eb397c-0f0a-48f2-a4a7-a39c38857565))
|
||||
(fp_poly (pts
|
||||
(xy 0.28956 -0.60198)
|
||||
(xy 0.59944 -0.60198)
|
||||
(xy 0.59944 -0.25146)
|
||||
(xy 0.28956 -0.25146)
|
||||
(xy 0.28956 -0.45212)
|
||||
) (layer "F.Paste") (width 0.01) (fill solid) (tstamp f157df02-fcb0-4ae7-85ca-bfc4444eda90))
|
||||
(fp_poly (pts
|
||||
(xy -0.60198 0.24892)
|
||||
(xy -0.2921 0.24892)
|
||||
(xy -0.2921 0.59944)
|
||||
(xy -0.60198 0.59944)
|
||||
(xy -0.60198 0.39878)
|
||||
) (layer "F.Paste") (width 0.01) (fill solid) (tstamp f3dab665-64fc-433e-8a62-3743b891ab83))
|
||||
(fp_line (start 0.6477 0.4191) (end 0.6477 0.65278) (layer "F.SilkS") (width 0.05) (tstamp 4ea989fb-9cda-4210-89d1-fe153727e40c))
|
||||
(fp_line (start 0.6477 0.65278) (end 0.44704 0.65278) (layer "F.SilkS") (width 0.05) (tstamp f64aa569-ea55-4736-9c96-3bfc2b30ccbd))
|
||||
(fp_line (start -0.8 -0.8) (end 0.8 -0.8) (layer "F.CrtYd") (width 0.05) (tstamp 05e65b06-4a6d-49f9-a6e8-c5bc53ef3e2a))
|
||||
(fp_line (start -0.8 0.8) (end 0.8 0.8) (layer "F.CrtYd") (width 0.05) (tstamp 39156b1c-bf91-438d-afb8-2007458c0b8e))
|
||||
(fp_line (start 0.8 0.8) (end 0.8 -0.8) (layer "F.CrtYd") (width 0.05) (tstamp 914c5b3a-21b5-462d-8f55-ca0b3cc81d2e))
|
||||
(fp_line (start -0.8 0.8) (end -0.8 -0.8) (layer "F.CrtYd") (width 0.05) (tstamp dd287ecc-48c7-4569-84ef-5639ce72358e))
|
||||
(fp_line (start -0.6 0.6) (end -0.6 -0.6) (layer "F.Fab") (width 0.1) (tstamp 08f7614b-9649-49c1-b63a-65c3d0a1ef41))
|
||||
(fp_line (start 0.3 0.6) (end -0.6 0.6) (layer "F.Fab") (width 0.1) (tstamp 27c16a37-d65b-4a83-af1a-5ee1a87062f4))
|
||||
(fp_line (start 0.3 0.6) (end 0.6 0.3) (layer "F.Fab") (width 0.1) (tstamp 4b62363e-5fde-40c0-ad96-ceb955d367f5))
|
||||
(fp_line (start 0.6 -0.6) (end 0.6 0.3) (layer "F.Fab") (width 0.1) (tstamp 77068506-5e69-47f6-8c18-559ed07a8a9f))
|
||||
(fp_line (start -0.6 -0.6) (end 0.6 -0.6) (layer "F.Fab") (width 0.1) (tstamp 9d536585-2f1d-4551-af3b-a0a4a6fa8aee))
|
||||
(pad "1" smd rect (at 0.38 0.38) (size 0.45 0.45) (layers "F.Cu" "F.Mask") (tstamp 1d4ec9d6-b4f1-4935-a655-c469bc01feb9))
|
||||
(pad "2" smd rect (at -0.38 0.38) (size 0.45 0.45) (layers "F.Cu" "F.Mask") (tstamp 62faf466-a5e1-4997-954a-e3f3f47e0a99))
|
||||
(pad "3" smd rect (at -0.38 -0.38) (size 0.45 0.45) (layers "F.Cu" "F.Mask") (tstamp 0ea92114-4add-4ede-abc4-5938831a4fe1))
|
||||
(pad "4" smd rect (at 0.38 -0.38) (size 0.45 0.45) (layers "F.Cu" "F.Mask") (tstamp 4cfa277c-b6f4-4575-8b74-ea83242e8813))
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/1010LED-FC-B1010RGBT-HG v3.step"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz -90 0 0))
|
||||
)
|
||||
)
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,582 @@
|
|||
ISO-10303-21;
|
||||
HEADER;
|
||||
/* Generated by software containing ST-Developer
|
||||
* from STEP Tools, Inc. (www.steptools.com)
|
||||
*/
|
||||
|
||||
FILE_DESCRIPTION(
|
||||
/* description */ (''),
|
||||
/* implementation_level */ '2;1');
|
||||
|
||||
FILE_NAME(
|
||||
/* name */
|
||||
'/Users/user/Desktop/2021-09-04 mullvad fpga/mta1-signer-master/hw/mta
|
||||
1_signer/pcb/mta1_signer_pmod/lib/kicad-pmod/pmod-conn_6x2.pretty/3d f
|
||||
ile/Ferriit bead-0603.step',
|
||||
/* time_stamp */ '2021-09-04T15:08:00+02:00',
|
||||
/* author */ (''),
|
||||
/* organization */ (''),
|
||||
/* preprocessor_version */ 'ST-DEVELOPER v18.1',
|
||||
/* originating_system */ 'Autodesk Translation Framework v10.10.0.1391',
|
||||
|
||||
/* authorisation */ '');
|
||||
|
||||
FILE_SCHEMA (('AUTOMOTIVE_DESIGN { 1 0 10303 214 3 1 1 }'));
|
||||
ENDSEC;
|
||||
|
||||
DATA;
|
||||
#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#13,#14,
|
||||
#15),#485);
|
||||
#11=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#492,#12);
|
||||
#12=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#16,#17,#18),#484);
|
||||
#13=STYLED_ITEM('',(#502),#16);
|
||||
#14=STYLED_ITEM('',(#503),#17);
|
||||
#15=STYLED_ITEM('',(#503),#18);
|
||||
#16=MANIFOLD_SOLID_BREP('Body1',#295);
|
||||
#17=MANIFOLD_SOLID_BREP('Body2',#296);
|
||||
#18=MANIFOLD_SOLID_BREP('Body3',#297);
|
||||
#19=FACE_OUTER_BOUND('',#37,.T.);
|
||||
#20=FACE_OUTER_BOUND('',#38,.T.);
|
||||
#21=FACE_OUTER_BOUND('',#39,.T.);
|
||||
#22=FACE_OUTER_BOUND('',#40,.T.);
|
||||
#23=FACE_OUTER_BOUND('',#41,.T.);
|
||||
#24=FACE_OUTER_BOUND('',#42,.T.);
|
||||
#25=FACE_OUTER_BOUND('',#43,.T.);
|
||||
#26=FACE_OUTER_BOUND('',#44,.T.);
|
||||
#27=FACE_OUTER_BOUND('',#45,.T.);
|
||||
#28=FACE_OUTER_BOUND('',#46,.T.);
|
||||
#29=FACE_OUTER_BOUND('',#47,.T.);
|
||||
#30=FACE_OUTER_BOUND('',#48,.T.);
|
||||
#31=FACE_OUTER_BOUND('',#49,.T.);
|
||||
#32=FACE_OUTER_BOUND('',#50,.T.);
|
||||
#33=FACE_OUTER_BOUND('',#51,.T.);
|
||||
#34=FACE_OUTER_BOUND('',#52,.T.);
|
||||
#35=FACE_OUTER_BOUND('',#53,.T.);
|
||||
#36=FACE_OUTER_BOUND('',#54,.T.);
|
||||
#37=EDGE_LOOP('',(#187,#188,#189,#190));
|
||||
#38=EDGE_LOOP('',(#191,#192,#193,#194));
|
||||
#39=EDGE_LOOP('',(#195,#196,#197,#198));
|
||||
#40=EDGE_LOOP('',(#199,#200,#201,#202));
|
||||
#41=EDGE_LOOP('',(#203,#204,#205,#206));
|
||||
#42=EDGE_LOOP('',(#207,#208,#209,#210));
|
||||
#43=EDGE_LOOP('',(#211,#212,#213,#214));
|
||||
#44=EDGE_LOOP('',(#215,#216,#217,#218));
|
||||
#45=EDGE_LOOP('',(#219,#220,#221,#222));
|
||||
#46=EDGE_LOOP('',(#223,#224,#225,#226));
|
||||
#47=EDGE_LOOP('',(#227,#228,#229,#230));
|
||||
#48=EDGE_LOOP('',(#231,#232,#233,#234));
|
||||
#49=EDGE_LOOP('',(#235,#236,#237,#238));
|
||||
#50=EDGE_LOOP('',(#239,#240,#241,#242));
|
||||
#51=EDGE_LOOP('',(#243,#244,#245,#246));
|
||||
#52=EDGE_LOOP('',(#247,#248,#249,#250));
|
||||
#53=EDGE_LOOP('',(#251,#252,#253,#254));
|
||||
#54=EDGE_LOOP('',(#255,#256,#257,#258));
|
||||
#55=LINE('',#407,#91);
|
||||
#56=LINE('',#409,#92);
|
||||
#57=LINE('',#411,#93);
|
||||
#58=LINE('',#412,#94);
|
||||
#59=LINE('',#415,#95);
|
||||
#60=LINE('',#417,#96);
|
||||
#61=LINE('',#418,#97);
|
||||
#62=LINE('',#421,#98);
|
||||
#63=LINE('',#423,#99);
|
||||
#64=LINE('',#424,#100);
|
||||
#65=LINE('',#426,#101);
|
||||
#66=LINE('',#427,#102);
|
||||
#67=LINE('',#433,#103);
|
||||
#68=LINE('',#435,#104);
|
||||
#69=LINE('',#437,#105);
|
||||
#70=LINE('',#438,#106);
|
||||
#71=LINE('',#441,#107);
|
||||
#72=LINE('',#443,#108);
|
||||
#73=LINE('',#444,#109);
|
||||
#74=LINE('',#447,#110);
|
||||
#75=LINE('',#449,#111);
|
||||
#76=LINE('',#450,#112);
|
||||
#77=LINE('',#452,#113);
|
||||
#78=LINE('',#453,#114);
|
||||
#79=LINE('',#459,#115);
|
||||
#80=LINE('',#461,#116);
|
||||
#81=LINE('',#463,#117);
|
||||
#82=LINE('',#464,#118);
|
||||
#83=LINE('',#467,#119);
|
||||
#84=LINE('',#469,#120);
|
||||
#85=LINE('',#470,#121);
|
||||
#86=LINE('',#473,#122);
|
||||
#87=LINE('',#475,#123);
|
||||
#88=LINE('',#476,#124);
|
||||
#89=LINE('',#478,#125);
|
||||
#90=LINE('',#479,#126);
|
||||
#91=VECTOR('',#333,10.);
|
||||
#92=VECTOR('',#334,10.);
|
||||
#93=VECTOR('',#335,10.);
|
||||
#94=VECTOR('',#336,10.);
|
||||
#95=VECTOR('',#339,10.);
|
||||
#96=VECTOR('',#340,10.);
|
||||
#97=VECTOR('',#341,10.);
|
||||
#98=VECTOR('',#344,10.);
|
||||
#99=VECTOR('',#345,10.);
|
||||
#100=VECTOR('',#346,10.);
|
||||
#101=VECTOR('',#349,10.);
|
||||
#102=VECTOR('',#350,10.);
|
||||
#103=VECTOR('',#357,10.);
|
||||
#104=VECTOR('',#358,10.);
|
||||
#105=VECTOR('',#359,10.);
|
||||
#106=VECTOR('',#360,10.);
|
||||
#107=VECTOR('',#363,10.);
|
||||
#108=VECTOR('',#364,10.);
|
||||
#109=VECTOR('',#365,10.);
|
||||
#110=VECTOR('',#368,10.);
|
||||
#111=VECTOR('',#369,10.);
|
||||
#112=VECTOR('',#370,10.);
|
||||
#113=VECTOR('',#373,10.);
|
||||
#114=VECTOR('',#374,10.);
|
||||
#115=VECTOR('',#381,10.);
|
||||
#116=VECTOR('',#382,10.);
|
||||
#117=VECTOR('',#383,10.);
|
||||
#118=VECTOR('',#384,10.);
|
||||
#119=VECTOR('',#387,10.);
|
||||
#120=VECTOR('',#388,10.);
|
||||
#121=VECTOR('',#389,10.);
|
||||
#122=VECTOR('',#392,10.);
|
||||
#123=VECTOR('',#393,10.);
|
||||
#124=VECTOR('',#394,10.);
|
||||
#125=VECTOR('',#397,10.);
|
||||
#126=VECTOR('',#398,10.);
|
||||
#127=VERTEX_POINT('',#405);
|
||||
#128=VERTEX_POINT('',#406);
|
||||
#129=VERTEX_POINT('',#408);
|
||||
#130=VERTEX_POINT('',#410);
|
||||
#131=VERTEX_POINT('',#414);
|
||||
#132=VERTEX_POINT('',#416);
|
||||
#133=VERTEX_POINT('',#420);
|
||||
#134=VERTEX_POINT('',#422);
|
||||
#135=VERTEX_POINT('',#431);
|
||||
#136=VERTEX_POINT('',#432);
|
||||
#137=VERTEX_POINT('',#434);
|
||||
#138=VERTEX_POINT('',#436);
|
||||
#139=VERTEX_POINT('',#440);
|
||||
#140=VERTEX_POINT('',#442);
|
||||
#141=VERTEX_POINT('',#446);
|
||||
#142=VERTEX_POINT('',#448);
|
||||
#143=VERTEX_POINT('',#457);
|
||||
#144=VERTEX_POINT('',#458);
|
||||
#145=VERTEX_POINT('',#460);
|
||||
#146=VERTEX_POINT('',#462);
|
||||
#147=VERTEX_POINT('',#466);
|
||||
#148=VERTEX_POINT('',#468);
|
||||
#149=VERTEX_POINT('',#472);
|
||||
#150=VERTEX_POINT('',#474);
|
||||
#151=EDGE_CURVE('',#127,#128,#55,.T.);
|
||||
#152=EDGE_CURVE('',#128,#129,#56,.T.);
|
||||
#153=EDGE_CURVE('',#130,#129,#57,.T.);
|
||||
#154=EDGE_CURVE('',#127,#130,#58,.T.);
|
||||
#155=EDGE_CURVE('',#127,#131,#59,.T.);
|
||||
#156=EDGE_CURVE('',#132,#130,#60,.T.);
|
||||
#157=EDGE_CURVE('',#131,#132,#61,.T.);
|
||||
#158=EDGE_CURVE('',#133,#131,#62,.T.);
|
||||
#159=EDGE_CURVE('',#134,#132,#63,.T.);
|
||||
#160=EDGE_CURVE('',#133,#134,#64,.T.);
|
||||
#161=EDGE_CURVE('',#128,#133,#65,.T.);
|
||||
#162=EDGE_CURVE('',#129,#134,#66,.T.);
|
||||
#163=EDGE_CURVE('',#135,#136,#67,.T.);
|
||||
#164=EDGE_CURVE('',#136,#137,#68,.T.);
|
||||
#165=EDGE_CURVE('',#138,#137,#69,.T.);
|
||||
#166=EDGE_CURVE('',#135,#138,#70,.T.);
|
||||
#167=EDGE_CURVE('',#139,#135,#71,.T.);
|
||||
#168=EDGE_CURVE('',#140,#138,#72,.T.);
|
||||
#169=EDGE_CURVE('',#139,#140,#73,.T.);
|
||||
#170=EDGE_CURVE('',#141,#139,#74,.T.);
|
||||
#171=EDGE_CURVE('',#142,#140,#75,.T.);
|
||||
#172=EDGE_CURVE('',#141,#142,#76,.T.);
|
||||
#173=EDGE_CURVE('',#136,#141,#77,.T.);
|
||||
#174=EDGE_CURVE('',#137,#142,#78,.T.);
|
||||
#175=EDGE_CURVE('',#143,#144,#79,.T.);
|
||||
#176=EDGE_CURVE('',#144,#145,#80,.T.);
|
||||
#177=EDGE_CURVE('',#146,#145,#81,.T.);
|
||||
#178=EDGE_CURVE('',#143,#146,#82,.T.);
|
||||
#179=EDGE_CURVE('',#143,#147,#83,.T.);
|
||||
#180=EDGE_CURVE('',#148,#146,#84,.T.);
|
||||
#181=EDGE_CURVE('',#147,#148,#85,.T.);
|
||||
#182=EDGE_CURVE('',#149,#147,#86,.T.);
|
||||
#183=EDGE_CURVE('',#150,#148,#87,.T.);
|
||||
#184=EDGE_CURVE('',#149,#150,#88,.T.);
|
||||
#185=EDGE_CURVE('',#144,#149,#89,.T.);
|
||||
#186=EDGE_CURVE('',#145,#150,#90,.T.);
|
||||
#187=ORIENTED_EDGE('',*,*,#151,.T.);
|
||||
#188=ORIENTED_EDGE('',*,*,#152,.T.);
|
||||
#189=ORIENTED_EDGE('',*,*,#153,.F.);
|
||||
#190=ORIENTED_EDGE('',*,*,#154,.F.);
|
||||
#191=ORIENTED_EDGE('',*,*,#155,.F.);
|
||||
#192=ORIENTED_EDGE('',*,*,#154,.T.);
|
||||
#193=ORIENTED_EDGE('',*,*,#156,.F.);
|
||||
#194=ORIENTED_EDGE('',*,*,#157,.F.);
|
||||
#195=ORIENTED_EDGE('',*,*,#158,.T.);
|
||||
#196=ORIENTED_EDGE('',*,*,#157,.T.);
|
||||
#197=ORIENTED_EDGE('',*,*,#159,.F.);
|
||||
#198=ORIENTED_EDGE('',*,*,#160,.F.);
|
||||
#199=ORIENTED_EDGE('',*,*,#161,.T.);
|
||||
#200=ORIENTED_EDGE('',*,*,#160,.T.);
|
||||
#201=ORIENTED_EDGE('',*,*,#162,.F.);
|
||||
#202=ORIENTED_EDGE('',*,*,#152,.F.);
|
||||
#203=ORIENTED_EDGE('',*,*,#162,.T.);
|
||||
#204=ORIENTED_EDGE('',*,*,#159,.T.);
|
||||
#205=ORIENTED_EDGE('',*,*,#156,.T.);
|
||||
#206=ORIENTED_EDGE('',*,*,#153,.T.);
|
||||
#207=ORIENTED_EDGE('',*,*,#161,.F.);
|
||||
#208=ORIENTED_EDGE('',*,*,#151,.F.);
|
||||
#209=ORIENTED_EDGE('',*,*,#155,.T.);
|
||||
#210=ORIENTED_EDGE('',*,*,#158,.F.);
|
||||
#211=ORIENTED_EDGE('',*,*,#163,.T.);
|
||||
#212=ORIENTED_EDGE('',*,*,#164,.T.);
|
||||
#213=ORIENTED_EDGE('',*,*,#165,.F.);
|
||||
#214=ORIENTED_EDGE('',*,*,#166,.F.);
|
||||
#215=ORIENTED_EDGE('',*,*,#167,.T.);
|
||||
#216=ORIENTED_EDGE('',*,*,#166,.T.);
|
||||
#217=ORIENTED_EDGE('',*,*,#168,.F.);
|
||||
#218=ORIENTED_EDGE('',*,*,#169,.F.);
|
||||
#219=ORIENTED_EDGE('',*,*,#170,.T.);
|
||||
#220=ORIENTED_EDGE('',*,*,#169,.T.);
|
||||
#221=ORIENTED_EDGE('',*,*,#171,.F.);
|
||||
#222=ORIENTED_EDGE('',*,*,#172,.F.);
|
||||
#223=ORIENTED_EDGE('',*,*,#173,.T.);
|
||||
#224=ORIENTED_EDGE('',*,*,#172,.T.);
|
||||
#225=ORIENTED_EDGE('',*,*,#174,.F.);
|
||||
#226=ORIENTED_EDGE('',*,*,#164,.F.);
|
||||
#227=ORIENTED_EDGE('',*,*,#174,.T.);
|
||||
#228=ORIENTED_EDGE('',*,*,#171,.T.);
|
||||
#229=ORIENTED_EDGE('',*,*,#168,.T.);
|
||||
#230=ORIENTED_EDGE('',*,*,#165,.T.);
|
||||
#231=ORIENTED_EDGE('',*,*,#173,.F.);
|
||||
#232=ORIENTED_EDGE('',*,*,#163,.F.);
|
||||
#233=ORIENTED_EDGE('',*,*,#167,.F.);
|
||||
#234=ORIENTED_EDGE('',*,*,#170,.F.);
|
||||
#235=ORIENTED_EDGE('',*,*,#175,.T.);
|
||||
#236=ORIENTED_EDGE('',*,*,#176,.T.);
|
||||
#237=ORIENTED_EDGE('',*,*,#177,.F.);
|
||||
#238=ORIENTED_EDGE('',*,*,#178,.F.);
|
||||
#239=ORIENTED_EDGE('',*,*,#179,.F.);
|
||||
#240=ORIENTED_EDGE('',*,*,#178,.T.);
|
||||
#241=ORIENTED_EDGE('',*,*,#180,.F.);
|
||||
#242=ORIENTED_EDGE('',*,*,#181,.F.);
|
||||
#243=ORIENTED_EDGE('',*,*,#182,.T.);
|
||||
#244=ORIENTED_EDGE('',*,*,#181,.T.);
|
||||
#245=ORIENTED_EDGE('',*,*,#183,.F.);
|
||||
#246=ORIENTED_EDGE('',*,*,#184,.F.);
|
||||
#247=ORIENTED_EDGE('',*,*,#185,.T.);
|
||||
#248=ORIENTED_EDGE('',*,*,#184,.T.);
|
||||
#249=ORIENTED_EDGE('',*,*,#186,.F.);
|
||||
#250=ORIENTED_EDGE('',*,*,#176,.F.);
|
||||
#251=ORIENTED_EDGE('',*,*,#186,.T.);
|
||||
#252=ORIENTED_EDGE('',*,*,#183,.T.);
|
||||
#253=ORIENTED_EDGE('',*,*,#180,.T.);
|
||||
#254=ORIENTED_EDGE('',*,*,#177,.T.);
|
||||
#255=ORIENTED_EDGE('',*,*,#185,.F.);
|
||||
#256=ORIENTED_EDGE('',*,*,#175,.F.);
|
||||
#257=ORIENTED_EDGE('',*,*,#179,.T.);
|
||||
#258=ORIENTED_EDGE('',*,*,#182,.F.);
|
||||
#259=PLANE('',#311);
|
||||
#260=PLANE('',#312);
|
||||
#261=PLANE('',#313);
|
||||
#262=PLANE('',#314);
|
||||
#263=PLANE('',#315);
|
||||
#264=PLANE('',#316);
|
||||
#265=PLANE('',#317);
|
||||
#266=PLANE('',#318);
|
||||
#267=PLANE('',#319);
|
||||
#268=PLANE('',#320);
|
||||
#269=PLANE('',#321);
|
||||
#270=PLANE('',#322);
|
||||
#271=PLANE('',#323);
|
||||
#272=PLANE('',#324);
|
||||
#273=PLANE('',#325);
|
||||
#274=PLANE('',#326);
|
||||
#275=PLANE('',#327);
|
||||
#276=PLANE('',#328);
|
||||
#277=ADVANCED_FACE('',(#19),#259,.T.);
|
||||
#278=ADVANCED_FACE('',(#20),#260,.T.);
|
||||
#279=ADVANCED_FACE('',(#21),#261,.T.);
|
||||
#280=ADVANCED_FACE('',(#22),#262,.T.);
|
||||
#281=ADVANCED_FACE('',(#23),#263,.T.);
|
||||
#282=ADVANCED_FACE('',(#24),#264,.F.);
|
||||
#283=ADVANCED_FACE('',(#25),#265,.T.);
|
||||
#284=ADVANCED_FACE('',(#26),#266,.T.);
|
||||
#285=ADVANCED_FACE('',(#27),#267,.T.);
|
||||
#286=ADVANCED_FACE('',(#28),#268,.T.);
|
||||
#287=ADVANCED_FACE('',(#29),#269,.T.);
|
||||
#288=ADVANCED_FACE('',(#30),#270,.F.);
|
||||
#289=ADVANCED_FACE('',(#31),#271,.T.);
|
||||
#290=ADVANCED_FACE('',(#32),#272,.T.);
|
||||
#291=ADVANCED_FACE('',(#33),#273,.T.);
|
||||
#292=ADVANCED_FACE('',(#34),#274,.T.);
|
||||
#293=ADVANCED_FACE('',(#35),#275,.T.);
|
||||
#294=ADVANCED_FACE('',(#36),#276,.F.);
|
||||
#295=CLOSED_SHELL('',(#277,#278,#279,#280,#281,#282));
|
||||
#296=CLOSED_SHELL('',(#283,#284,#285,#286,#287,#288));
|
||||
#297=CLOSED_SHELL('',(#289,#290,#291,#292,#293,#294));
|
||||
#298=DERIVED_UNIT_ELEMENT(#300,1.);
|
||||
#299=DERIVED_UNIT_ELEMENT(#487,-3.);
|
||||
#300=(
|
||||
MASS_UNIT()
|
||||
NAMED_UNIT(*)
|
||||
SI_UNIT(.KILO.,.GRAM.)
|
||||
);
|
||||
#301=DERIVED_UNIT((#298,#299));
|
||||
#302=MEASURE_REPRESENTATION_ITEM('density measure',
|
||||
POSITIVE_RATIO_MEASURE(7850.),#301);
|
||||
#303=PROPERTY_DEFINITION_REPRESENTATION(#308,#305);
|
||||
#304=PROPERTY_DEFINITION_REPRESENTATION(#309,#306);
|
||||
#305=REPRESENTATION('material name',(#307),#484);
|
||||
#306=REPRESENTATION('density',(#302),#484);
|
||||
#307=DESCRIPTIVE_REPRESENTATION_ITEM('Steel','Steel');
|
||||
#308=PROPERTY_DEFINITION('material property','material name',#494);
|
||||
#309=PROPERTY_DEFINITION('material property','density of part',#494);
|
||||
#310=AXIS2_PLACEMENT_3D('placement',#403,#329,#330);
|
||||
#311=AXIS2_PLACEMENT_3D('',#404,#331,#332);
|
||||
#312=AXIS2_PLACEMENT_3D('',#413,#337,#338);
|
||||
#313=AXIS2_PLACEMENT_3D('',#419,#342,#343);
|
||||
#314=AXIS2_PLACEMENT_3D('',#425,#347,#348);
|
||||
#315=AXIS2_PLACEMENT_3D('',#428,#351,#352);
|
||||
#316=AXIS2_PLACEMENT_3D('',#429,#353,#354);
|
||||
#317=AXIS2_PLACEMENT_3D('',#430,#355,#356);
|
||||
#318=AXIS2_PLACEMENT_3D('',#439,#361,#362);
|
||||
#319=AXIS2_PLACEMENT_3D('',#445,#366,#367);
|
||||
#320=AXIS2_PLACEMENT_3D('',#451,#371,#372);
|
||||
#321=AXIS2_PLACEMENT_3D('',#454,#375,#376);
|
||||
#322=AXIS2_PLACEMENT_3D('',#455,#377,#378);
|
||||
#323=AXIS2_PLACEMENT_3D('',#456,#379,#380);
|
||||
#324=AXIS2_PLACEMENT_3D('',#465,#385,#386);
|
||||
#325=AXIS2_PLACEMENT_3D('',#471,#390,#391);
|
||||
#326=AXIS2_PLACEMENT_3D('',#477,#395,#396);
|
||||
#327=AXIS2_PLACEMENT_3D('',#480,#399,#400);
|
||||
#328=AXIS2_PLACEMENT_3D('',#481,#401,#402);
|
||||
#329=DIRECTION('axis',(0.,0.,1.));
|
||||
#330=DIRECTION('refdir',(1.,0.,0.));
|
||||
#331=DIRECTION('center_axis',(0.,0.,-1.));
|
||||
#332=DIRECTION('ref_axis',(-1.,0.,0.));
|
||||
#333=DIRECTION('',(-1.,0.,0.));
|
||||
#334=DIRECTION('',(0.,1.,0.));
|
||||
#335=DIRECTION('',(-1.,0.,0.));
|
||||
#336=DIRECTION('',(0.,1.,0.));
|
||||
#337=DIRECTION('center_axis',(1.,0.,-5.55111512312578E-15));
|
||||
#338=DIRECTION('ref_axis',(-5.55111512312578E-15,0.,-1.));
|
||||
#339=DIRECTION('',(5.55111512312578E-15,0.,1.));
|
||||
#340=DIRECTION('',(-5.55111512312578E-15,0.,-1.));
|
||||
#341=DIRECTION('',(0.,1.,0.));
|
||||
#342=DIRECTION('center_axis',(1.38777878078145E-15,0.,1.));
|
||||
#343=DIRECTION('ref_axis',(1.,0.,-1.38777878078145E-15));
|
||||
#344=DIRECTION('',(1.,0.,-1.38777878078145E-15));
|
||||
#345=DIRECTION('',(1.,0.,-1.38777878078145E-15));
|
||||
#346=DIRECTION('',(0.,1.,0.));
|
||||
#347=DIRECTION('center_axis',(-1.,0.,0.));
|
||||
#348=DIRECTION('ref_axis',(0.,0.,1.));
|
||||
#349=DIRECTION('',(0.,0.,1.));
|
||||
#350=DIRECTION('',(0.,0.,1.));
|
||||
#351=DIRECTION('center_axis',(0.,1.,0.));
|
||||
#352=DIRECTION('ref_axis',(0.,0.,1.));
|
||||
#353=DIRECTION('center_axis',(0.,1.,0.));
|
||||
#354=DIRECTION('ref_axis',(1.,0.,0.));
|
||||
#355=DIRECTION('center_axis',(0.,0.,-1.));
|
||||
#356=DIRECTION('ref_axis',(-1.,0.,0.));
|
||||
#357=DIRECTION('',(-1.,0.,0.));
|
||||
#358=DIRECTION('',(0.,1.,0.));
|
||||
#359=DIRECTION('',(-1.,0.,0.));
|
||||
#360=DIRECTION('',(0.,1.,0.));
|
||||
#361=DIRECTION('center_axis',(1.,0.,-3.46944695195362E-16));
|
||||
#362=DIRECTION('ref_axis',(-3.46944695195362E-16,0.,-1.));
|
||||
#363=DIRECTION('',(-3.46944695195362E-16,0.,-1.));
|
||||
#364=DIRECTION('',(-3.46944695195362E-16,0.,-1.));
|
||||
#365=DIRECTION('',(0.,1.,0.));
|
||||
#366=DIRECTION('center_axis',(1.38777878078145E-15,0.,1.));
|
||||
#367=DIRECTION('ref_axis',(1.,0.,-1.38777878078145E-15));
|
||||
#368=DIRECTION('',(1.,0.,-1.38777878078145E-15));
|
||||
#369=DIRECTION('',(1.,0.,-1.38777878078145E-15));
|
||||
#370=DIRECTION('',(0.,1.,0.));
|
||||
#371=DIRECTION('center_axis',(-1.,0.,5.55111512312578E-15));
|
||||
#372=DIRECTION('ref_axis',(5.55111512312578E-15,0.,1.));
|
||||
#373=DIRECTION('',(5.55111512312578E-15,0.,1.));
|
||||
#374=DIRECTION('',(5.55111512312578E-15,0.,1.));
|
||||
#375=DIRECTION('center_axis',(0.,1.,0.));
|
||||
#376=DIRECTION('ref_axis',(0.,0.,1.));
|
||||
#377=DIRECTION('center_axis',(0.,1.,0.));
|
||||
#378=DIRECTION('ref_axis',(1.,0.,0.));
|
||||
#379=DIRECTION('center_axis',(0.,0.,-1.));
|
||||
#380=DIRECTION('ref_axis',(-1.,0.,0.));
|
||||
#381=DIRECTION('',(-1.,0.,0.));
|
||||
#382=DIRECTION('',(0.,1.,0.));
|
||||
#383=DIRECTION('',(-1.,0.,0.));
|
||||
#384=DIRECTION('',(0.,1.,0.));
|
||||
#385=DIRECTION('center_axis',(1.,0.,0.));
|
||||
#386=DIRECTION('ref_axis',(0.,0.,-1.));
|
||||
#387=DIRECTION('',(0.,0.,1.));
|
||||
#388=DIRECTION('',(0.,0.,-1.));
|
||||
#389=DIRECTION('',(0.,1.,0.));
|
||||
#390=DIRECTION('center_axis',(1.38777878078145E-15,0.,1.));
|
||||
#391=DIRECTION('ref_axis',(1.,0.,-1.38777878078145E-15));
|
||||
#392=DIRECTION('',(1.,0.,-1.38777878078145E-15));
|
||||
#393=DIRECTION('',(1.,0.,-1.38777878078145E-15));
|
||||
#394=DIRECTION('',(0.,1.,0.));
|
||||
#395=DIRECTION('center_axis',(-1.,0.,-3.46944695195361E-16));
|
||||
#396=DIRECTION('ref_axis',(-3.46944695195361E-16,0.,1.));
|
||||
#397=DIRECTION('',(-3.46944695195361E-16,0.,1.));
|
||||
#398=DIRECTION('',(-3.46944695195361E-16,0.,1.));
|
||||
#399=DIRECTION('center_axis',(0.,1.,0.));
|
||||
#400=DIRECTION('ref_axis',(0.,0.,1.));
|
||||
#401=DIRECTION('center_axis',(0.,1.,0.));
|
||||
#402=DIRECTION('ref_axis',(1.,0.,0.));
|
||||
#403=CARTESIAN_POINT('',(0.,0.,0.));
|
||||
#404=CARTESIAN_POINT('Origin',(0.399999999999999,0.,-0.4));
|
||||
#405=CARTESIAN_POINT('',(0.399999999999999,0.,-0.400000000000002));
|
||||
#406=CARTESIAN_POINT('',(-0.400000000000001,0.,-0.4));
|
||||
#407=CARTESIAN_POINT('',(0.799999999999999,0.,-0.4));
|
||||
#408=CARTESIAN_POINT('',(-0.400000000000001,0.6,-0.4));
|
||||
#409=CARTESIAN_POINT('',(-0.400000000000001,0.,-0.4));
|
||||
#410=CARTESIAN_POINT('',(0.399999999999999,0.6,-0.400000000000002));
|
||||
#411=CARTESIAN_POINT('',(0.799999999999999,0.6,-0.4));
|
||||
#412=CARTESIAN_POINT('',(0.399999999999999,0.,-0.400000000000002));
|
||||
#413=CARTESIAN_POINT('Origin',(0.400000000000003,0.,0.399999999999999));
|
||||
#414=CARTESIAN_POINT('',(0.400000000000003,0.,0.399999999999999));
|
||||
#415=CARTESIAN_POINT('',(0.399999999999999,0.,-0.400000000000002));
|
||||
#416=CARTESIAN_POINT('',(0.400000000000003,0.6,0.399999999999999));
|
||||
#417=CARTESIAN_POINT('',(0.399999999999999,0.6,-0.400000000000002));
|
||||
#418=CARTESIAN_POINT('',(0.400000000000003,0.,0.399999999999999));
|
||||
#419=CARTESIAN_POINT('Origin',(-0.400000000000001,0.,0.400000000000001));
|
||||
#420=CARTESIAN_POINT('',(-0.400000000000001,0.,0.400000000000001));
|
||||
#421=CARTESIAN_POINT('',(-0.800000000000001,0.,0.400000000000001));
|
||||
#422=CARTESIAN_POINT('',(-0.400000000000001,0.6,0.400000000000001));
|
||||
#423=CARTESIAN_POINT('',(-0.800000000000001,0.6,0.400000000000001));
|
||||
#424=CARTESIAN_POINT('',(-0.400000000000001,0.,0.400000000000001));
|
||||
#425=CARTESIAN_POINT('Origin',(-0.400000000000001,0.,-0.4));
|
||||
#426=CARTESIAN_POINT('',(-0.400000000000001,0.,-0.4));
|
||||
#427=CARTESIAN_POINT('',(-0.400000000000001,0.6,-0.4));
|
||||
#428=CARTESIAN_POINT('Origin',(1.11022302462516E-15,0.6,-5.55111512312578E-16));
|
||||
#429=CARTESIAN_POINT('Origin',(1.11022302462516E-15,0.,-5.55111512312578E-16));
|
||||
#430=CARTESIAN_POINT('Origin',(0.799999999999999,0.,-0.4));
|
||||
#431=CARTESIAN_POINT('',(0.799999999999999,0.,-0.4));
|
||||
#432=CARTESIAN_POINT('',(0.399999999999999,0.,-0.400000000000002));
|
||||
#433=CARTESIAN_POINT('',(0.799999999999999,0.,-0.4));
|
||||
#434=CARTESIAN_POINT('',(0.399999999999999,0.6,-0.400000000000002));
|
||||
#435=CARTESIAN_POINT('',(0.399999999999999,0.,-0.400000000000002));
|
||||
#436=CARTESIAN_POINT('',(0.799999999999999,0.6,-0.4));
|
||||
#437=CARTESIAN_POINT('',(0.799999999999999,0.6,-0.4));
|
||||
#438=CARTESIAN_POINT('',(0.799999999999999,0.,-0.4));
|
||||
#439=CARTESIAN_POINT('Origin',(0.799999999999999,0.,0.399999999999999));
|
||||
#440=CARTESIAN_POINT('',(0.799999999999999,0.,0.399999999999999));
|
||||
#441=CARTESIAN_POINT('',(0.799999999999999,0.,0.399999999999999));
|
||||
#442=CARTESIAN_POINT('',(0.799999999999999,0.6,0.399999999999999));
|
||||
#443=CARTESIAN_POINT('',(0.799999999999999,0.6,0.399999999999999));
|
||||
#444=CARTESIAN_POINT('',(0.799999999999999,0.,0.399999999999999));
|
||||
#445=CARTESIAN_POINT('Origin',(0.400000000000003,0.,0.4));
|
||||
#446=CARTESIAN_POINT('',(0.400000000000003,0.,0.399999999999999));
|
||||
#447=CARTESIAN_POINT('',(-0.800000000000001,0.,0.400000000000001));
|
||||
#448=CARTESIAN_POINT('',(0.400000000000003,0.6,0.399999999999999));
|
||||
#449=CARTESIAN_POINT('',(-0.800000000000001,0.6,0.400000000000001));
|
||||
#450=CARTESIAN_POINT('',(0.400000000000003,0.,0.399999999999999));
|
||||
#451=CARTESIAN_POINT('Origin',(0.399999999999999,0.,-0.400000000000002));
|
||||
#452=CARTESIAN_POINT('',(0.399999999999999,0.,-0.400000000000002));
|
||||
#453=CARTESIAN_POINT('',(0.399999999999999,0.6,-0.400000000000002));
|
||||
#454=CARTESIAN_POINT('Origin',(0.599999999999999,0.6,-1.11022302462516E-15));
|
||||
#455=CARTESIAN_POINT('Origin',(0.599999999999999,0.,-1.11022302462516E-15));
|
||||
#456=CARTESIAN_POINT('Origin',(-0.400000000000001,0.,-0.4));
|
||||
#457=CARTESIAN_POINT('',(-0.400000000000001,0.,-0.4));
|
||||
#458=CARTESIAN_POINT('',(-0.800000000000001,0.,-0.4));
|
||||
#459=CARTESIAN_POINT('',(0.799999999999999,0.,-0.4));
|
||||
#460=CARTESIAN_POINT('',(-0.800000000000001,0.6,-0.4));
|
||||
#461=CARTESIAN_POINT('',(-0.800000000000001,0.,-0.4));
|
||||
#462=CARTESIAN_POINT('',(-0.400000000000001,0.6,-0.4));
|
||||
#463=CARTESIAN_POINT('',(0.799999999999999,0.6,-0.4));
|
||||
#464=CARTESIAN_POINT('',(-0.400000000000001,0.,-0.4));
|
||||
#465=CARTESIAN_POINT('Origin',(-0.400000000000001,0.,0.400000000000001));
|
||||
#466=CARTESIAN_POINT('',(-0.400000000000001,0.,0.400000000000001));
|
||||
#467=CARTESIAN_POINT('',(-0.400000000000001,0.,-0.4));
|
||||
#468=CARTESIAN_POINT('',(-0.400000000000001,0.6,0.400000000000001));
|
||||
#469=CARTESIAN_POINT('',(-0.400000000000001,0.6,-0.4));
|
||||
#470=CARTESIAN_POINT('',(-0.400000000000001,0.,0.400000000000001));
|
||||
#471=CARTESIAN_POINT('Origin',(-0.800000000000001,0.,0.400000000000001));
|
||||
#472=CARTESIAN_POINT('',(-0.800000000000001,0.,0.400000000000001));
|
||||
#473=CARTESIAN_POINT('',(-0.800000000000001,0.,0.400000000000001));
|
||||
#474=CARTESIAN_POINT('',(-0.800000000000001,0.6,0.400000000000001));
|
||||
#475=CARTESIAN_POINT('',(-0.800000000000001,0.6,0.400000000000001));
|
||||
#476=CARTESIAN_POINT('',(-0.800000000000001,0.,0.400000000000001));
|
||||
#477=CARTESIAN_POINT('Origin',(-0.800000000000001,0.,-0.4));
|
||||
#478=CARTESIAN_POINT('',(-0.800000000000001,0.,-0.4));
|
||||
#479=CARTESIAN_POINT('',(-0.800000000000001,0.6,-0.4));
|
||||
#480=CARTESIAN_POINT('Origin',(-0.600000000000001,0.6,8.32667268468867E-16));
|
||||
#481=CARTESIAN_POINT('Origin',(-0.600000000000001,0.,8.32667268468867E-16));
|
||||
#482=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#486,
|
||||
'DISTANCE_ACCURACY_VALUE',
|
||||
'Maximum model space distance between geometric entities at asserted c
|
||||
onnectivities');
|
||||
#483=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#486,
|
||||
'DISTANCE_ACCURACY_VALUE',
|
||||
'Maximum model space distance between geometric entities at asserted c
|
||||
onnectivities');
|
||||
#484=(
|
||||
GEOMETRIC_REPRESENTATION_CONTEXT(3)
|
||||
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#482))
|
||||
GLOBAL_UNIT_ASSIGNED_CONTEXT((#486,#488,#489))
|
||||
REPRESENTATION_CONTEXT('','3D')
|
||||
);
|
||||
#485=(
|
||||
GEOMETRIC_REPRESENTATION_CONTEXT(3)
|
||||
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#483))
|
||||
GLOBAL_UNIT_ASSIGNED_CONTEXT((#486,#488,#489))
|
||||
REPRESENTATION_CONTEXT('','3D')
|
||||
);
|
||||
#486=(
|
||||
LENGTH_UNIT()
|
||||
NAMED_UNIT(*)
|
||||
SI_UNIT(.MILLI.,.METRE.)
|
||||
);
|
||||
#487=(
|
||||
LENGTH_UNIT()
|
||||
NAMED_UNIT(*)
|
||||
SI_UNIT($,.METRE.)
|
||||
);
|
||||
#488=(
|
||||
NAMED_UNIT(*)
|
||||
PLANE_ANGLE_UNIT()
|
||||
SI_UNIT($,.RADIAN.)
|
||||
);
|
||||
#489=(
|
||||
NAMED_UNIT(*)
|
||||
SI_UNIT($,.STERADIAN.)
|
||||
SOLID_ANGLE_UNIT()
|
||||
);
|
||||
#490=SHAPE_DEFINITION_REPRESENTATION(#491,#492);
|
||||
#491=PRODUCT_DEFINITION_SHAPE('',$,#494);
|
||||
#492=SHAPE_REPRESENTATION('',(#310),#484);
|
||||
#493=PRODUCT_DEFINITION_CONTEXT('part definition',#498,'design');
|
||||
#494=PRODUCT_DEFINITION('Ferriit bead','Ferriit bead v1',#495,#493);
|
||||
#495=PRODUCT_DEFINITION_FORMATION('',$,#500);
|
||||
#496=PRODUCT_RELATED_PRODUCT_CATEGORY('Ferriit bead v1',
|
||||
'Ferriit bead v1',(#500));
|
||||
#497=APPLICATION_PROTOCOL_DEFINITION('international standard',
|
||||
'automotive_design',2009,#498);
|
||||
#498=APPLICATION_CONTEXT(
|
||||
'Core Data for Automotive Mechanical Design Process');
|
||||
#499=PRODUCT_CONTEXT('part definition',#498,'mechanical');
|
||||
#500=PRODUCT('Ferriit bead','Ferriit bead v1',$,(#499));
|
||||
#501=PRESENTATION_STYLE_ASSIGNMENT((#504));
|
||||
#502=PRESENTATION_STYLE_ASSIGNMENT((#505));
|
||||
#503=PRESENTATION_STYLE_ASSIGNMENT((#506));
|
||||
#504=SURFACE_STYLE_USAGE(.BOTH.,#507);
|
||||
#505=SURFACE_STYLE_USAGE(.BOTH.,#508);
|
||||
#506=SURFACE_STYLE_USAGE(.BOTH.,#509);
|
||||
#507=SURFACE_SIDE_STYLE('',(#510));
|
||||
#508=SURFACE_SIDE_STYLE('',(#511));
|
||||
#509=SURFACE_SIDE_STYLE('',(#512));
|
||||
#510=SURFACE_STYLE_FILL_AREA(#513);
|
||||
#511=SURFACE_STYLE_FILL_AREA(#514);
|
||||
#512=SURFACE_STYLE_FILL_AREA(#515);
|
||||
#513=FILL_AREA_STYLE('Steel - Satin',(#516));
|
||||
#514=FILL_AREA_STYLE('Steel - Satin',(#517));
|
||||
#515=FILL_AREA_STYLE('Lead - Satin',(#518));
|
||||
#516=FILL_AREA_STYLE_COLOUR('Steel - Satin',#519);
|
||||
#517=FILL_AREA_STYLE_COLOUR('Steel - Satin',#520);
|
||||
#518=FILL_AREA_STYLE_COLOUR('Lead - Satin',#521);
|
||||
#519=COLOUR_RGB('Steel - Satin',0.627450980392157,0.627450980392157,0.627450980392157);
|
||||
#520=COLOUR_RGB('Steel - Satin',0.47843137254902,0.392156862745098,0.266666666666667);
|
||||
#521=COLOUR_RGB('Lead - Satin',0.815686274509804,0.815686274509804,0.815686274509804);
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
35863
hw/boards/mta1-library/mta1.pretty/3d_models/ICE40UP5K-SG48ITR.step
Normal file
35863
hw/boards/mta1-library/mta1.pretty/3d_models/ICE40UP5K-SG48ITR.step
Normal file
File diff suppressed because it is too large
Load diff
2304
hw/boards/mta1-library/mta1.pretty/3d_models/MC2016Z.step
Normal file
2304
hw/boards/mta1-library/mta1.pretty/3d_models/MC2016Z.step
Normal file
File diff suppressed because it is too large
Load diff
5824
hw/boards/mta1-library/mta1.pretty/3d_models/MCP1824T.step
Normal file
5824
hw/boards/mta1-library/mta1.pretty/3d_models/MCP1824T.step
Normal file
File diff suppressed because it is too large
Load diff
7169
hw/boards/mta1-library/mta1.pretty/3d_models/U261-241N-4BS60.step
Normal file
7169
hw/boards/mta1-library/mta1.pretty/3d_models/U261-241N-4BS60.step
Normal file
File diff suppressed because it is too large
Load diff
1586
hw/boards/mta1-library/mta1.pretty/3d_models/USON_2X3.step
Normal file
1586
hw/boards/mta1-library/mta1.pretty/3d_models/USON_2X3.step
Normal file
File diff suppressed because it is too large
Load diff
22970
hw/boards/mta1-library/mta1.pretty/3d_models/molex_1054440001.stp
Normal file
22970
hw/boards/mta1-library/mta1.pretty/3d_models/molex_1054440001.stp
Normal file
File diff suppressed because it is too large
Load diff
12308
hw/boards/mta1-library/mta1.pretty/3d_models/mta1_usb_ch554_pogo.step
Normal file
12308
hw/boards/mta1-library/mta1.pretty/3d_models/mta1_usb_ch554_pogo.step
Normal file
File diff suppressed because it is too large
Load diff
17445
hw/boards/mta1-library/mta1.pretty/3d_models/u261-24xn-4bs60.stp
Normal file
17445
hw/boards/mta1-library/mta1.pretty/3d_models/u261-24xn-4bs60.stp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,40 @@
|
|||
(footprint "AP22802AW5-SOT-23-5" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 61367F51)
|
||||
(descr "5-pin SOT23 package")
|
||||
(tags "SOT-23-5")
|
||||
(attr smd)
|
||||
(fp_text reference "REF**" (at 0 -2.9) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 2592a4a3-bdaa-4fb0-9abb-8c21c03c0638)
|
||||
)
|
||||
(fp_text value "AP22802AW5-SOT-23-5" (at 0 2.9) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 03a09cf1-7d57-4196-9c02-dff2303bf34f)
|
||||
)
|
||||
(fp_text user "${REFERENCE}" (at 0 0 90) (layer "F.Fab")
|
||||
(effects (font (size 0.5 0.5) (thickness 0.075)))
|
||||
(tstamp 7cb260b0-5651-4e66-90db-eaf84bb25ba9)
|
||||
)
|
||||
(fp_line (start 0.9 -1.61) (end -1.55 -1.61) (layer "F.SilkS") (width 0.12) (tstamp 30dbb8a1-8117-428b-9603-593e1cd6f0b8))
|
||||
(fp_line (start -0.9 1.61) (end 0.9 1.61) (layer "F.SilkS") (width 0.12) (tstamp 5c7667ea-6990-4c08-81db-fa40fd866650))
|
||||
(fp_line (start 1.9 1.8) (end -1.9 1.8) (layer "F.CrtYd") (width 0.05) (tstamp 5ed94e14-a02a-4fc5-9bb4-abf168627729))
|
||||
(fp_line (start 1.9 -1.8) (end 1.9 1.8) (layer "F.CrtYd") (width 0.05) (tstamp d21bb4f3-d8fa-457f-87e5-0c9117c8c3c6))
|
||||
(fp_line (start -1.9 -1.8) (end 1.9 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp de8fc45e-5dda-42c6-98c2-4c0638f11efc))
|
||||
(fp_line (start -1.9 1.8) (end -1.9 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp ec654617-65dd-4207-b324-b0895176aa59))
|
||||
(fp_line (start -0.9 -0.9) (end -0.9 1.55) (layer "F.Fab") (width 0.1) (tstamp 5dca725c-29fd-4b5b-b012-830ab59914be))
|
||||
(fp_line (start 0.9 1.55) (end -0.9 1.55) (layer "F.Fab") (width 0.1) (tstamp a7f6f29a-97ab-47b4-980c-45f4600fdb97))
|
||||
(fp_line (start -0.9 -0.9) (end -0.25 -1.55) (layer "F.Fab") (width 0.1) (tstamp dc8e2523-4db6-4218-b74d-286ceb9e34fe))
|
||||
(fp_line (start 0.9 -1.55) (end 0.9 1.55) (layer "F.Fab") (width 0.1) (tstamp e9de2be6-f93f-4f60-8594-4ad9f53236a3))
|
||||
(fp_line (start 0.9 -1.55) (end -0.25 -1.55) (layer "F.Fab") (width 0.1) (tstamp f9d3815d-7f06-438b-a7cd-6a32a2763be6))
|
||||
(pad "1" smd rect (at -1.1 -0.95) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 3943437c-7fcb-4be3-88eb-7e08b4c71093))
|
||||
(pad "2" smd rect (at -1.1 0) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp b4008af9-04d0-41c9-9c35-f8b44c33ac9a))
|
||||
(pad "3" smd rect (at -1.1 0.95) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 81d091a7-dd43-4108-9bad-91f21605e2a9))
|
||||
(pad "4" smd rect (at 1.1 0.95) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 739d36b6-b48c-40ae-a97e-78e0165cc69e))
|
||||
(pad "5" smd rect (at 1.1 -0.95) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp d6093aa1-0151-4029-bd11-4474df94de39))
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/AP22802AW5-SOT23-5-MARKS XA7sE.step"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz -90 0 -90))
|
||||
)
|
||||
)
|
31
hw/boards/mta1-library/mta1.pretty/CAPC1005X06L.kicad_mod
Normal file
31
hw/boards/mta1-library/mta1.pretty/CAPC1005X06L.kicad_mod
Normal file
|
@ -0,0 +1,31 @@
|
|||
(module CAPC1005X06L (layer F.Cu) (tedit 6137303B)
|
||||
(descr "Capacitor SMD 0402 (1005 Metric), square (rectangular) end terminal, IPC_7351 least")
|
||||
(tags capacitor)
|
||||
(attr smd)
|
||||
(fp_text reference REF** (at 0 -1.16) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value CAPC1005X06L (at 0 1.16) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_line (start 0.91 0.46) (end -0.91 0.46) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 0.91 -0.46) (end 0.91 0.46) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.91 -0.46) (end 0.91 -0.46) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.91 0.46) (end -0.91 -0.46) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.107836 0.36) (end 0.107836 0.36) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -0.107836 -0.36) (end 0.107836 -0.36) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start 0.5 0.25) (end -0.5 0.25) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.5 -0.25) (end 0.5 0.25) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -0.5 -0.25) (end 0.5 -0.25) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -0.5 0.25) (end -0.5 -0.25) (layer F.Fab) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.25 0.25) (thickness 0.04)))
|
||||
)
|
||||
(pad 1 smd roundrect (at -0.39 0) (size 0.56 0.518) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
|
||||
(pad 2 smd roundrect (at 0.39 0) (size 0.56 0.518) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
|
||||
(model ${KICAD6_3DMODEL_DIR}/Capacitor_SMD.3dshapes/C_0402_1005Metric.wrl
|
||||
(at (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
31
hw/boards/mta1-library/mta1.pretty/CAPC1608X09L.kicad_mod
Normal file
31
hw/boards/mta1-library/mta1.pretty/CAPC1608X09L.kicad_mod
Normal file
|
@ -0,0 +1,31 @@
|
|||
(module CAPC1608X09L (layer F.Cu) (tedit 61373115)
|
||||
(descr "Capacitor SMD 0603 (1608 Metric), square (rectangular) end terminal, IPC_7351 least")
|
||||
(tags capacitor)
|
||||
(attr smd)
|
||||
(fp_text reference REF** (at 0 -1.43) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value CAPC1608X09L (at 0 1.43) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_line (start -0.8 0.4) (end -0.8 -0.4) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -0.8 -0.4) (end 0.8 -0.4) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.8 -0.4) (end 0.8 0.4) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.8 0.4) (end -0.8 0.4) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -0.14058 -0.51) (end 0.14058 -0.51) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -0.14058 0.51) (end 0.14058 0.51) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -1.48 0.73) (end -1.48 -0.73) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.48 -0.73) (end 1.48 -0.73) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.48 -0.73) (end 1.48 0.73) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.48 0.73) (end -1.48 0.73) (layer F.CrtYd) (width 0.05))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.4 0.4) (thickness 0.06)))
|
||||
)
|
||||
(pad 1 smd roundrect (at -0.65 0) (size 0.8 0.85) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
|
||||
(pad 2 smd roundrect (at 0.65 0) (size 0.8 0.85) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
|
||||
(model ${KICAD6_3DMODEL_DIR}/Capacitor_SMD.3dshapes/C_0603_1608Metric.wrl
|
||||
(at (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
31
hw/boards/mta1-library/mta1.pretty/ERJ2G(0402)_L.kicad_mod
Normal file
31
hw/boards/mta1-library/mta1.pretty/ERJ2G(0402)_L.kicad_mod
Normal file
|
@ -0,0 +1,31 @@
|
|||
(module "ERJ2G(0402)_L" (layer F.Cu) (tedit 6137302D)
|
||||
(descr "Resistor SMD 0402 (1005 Metric), square (rectangular) end terminal, IPC_7351 least")
|
||||
(tags resistor)
|
||||
(attr smd)
|
||||
(fp_text reference REF** (at 0 -1.17) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value "ERJ2G(0402)_L" (at 0 1.17) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_line (start -0.525 0.27) (end -0.525 -0.27) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -0.525 -0.27) (end 0.525 -0.27) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.525 -0.27) (end 0.525 0.27) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.525 0.27) (end -0.525 0.27) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -0.153641 -0.38) (end 0.153641 -0.38) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -0.153641 0.38) (end 0.153641 0.38) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -0.93 0.47) (end -0.93 -0.47) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.93 -0.47) (end 0.93 -0.47) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 0.93 -0.47) (end 0.93 0.47) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 0.93 0.47) (end -0.93 0.47) (layer F.CrtYd) (width 0.05))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.26 0.26) (thickness 0.04)))
|
||||
)
|
||||
(pad 1 smd roundrect (at -0.4 0) (size 0.45 0.45) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
|
||||
(pad 2 smd roundrect (at 0.4 0) (size 0.45 0.45) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
|
||||
(model ${KICAD6_3DMODEL_DIR}/Resistor_SMD.3dshapes/R_0402_1005Metric.wrl
|
||||
(at (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
|
@ -0,0 +1,72 @@
|
|||
(module FT2232H_MINI_MODULE (layer F.Cu) (tedit 616F3922)
|
||||
(fp_text reference REF** (at 0 0.5) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value FT2232H_MINI_MODULE (at 0 -2.54) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_line (start -14.605 34.29) (end -14.605 -1.27) (layer F.Fab) (width 0.12))
|
||||
(fp_line (start 14.605 34.29) (end -14.605 34.29) (layer F.Fab) (width 0.12))
|
||||
(fp_line (start 14.605 -1.27) (end 14.605 34.29) (layer F.Fab) (width 0.12))
|
||||
(fp_line (start -14.605 -1.27) (end 14.605 -1.27) (layer F.Fab) (width 0.12))
|
||||
(fp_line (start -13.97 34.29) (end -13.97 1.27) (layer F.CrtYd) (width 0.12))
|
||||
(fp_line (start -8.89 34.29) (end -13.97 34.29) (layer F.CrtYd) (width 0.12))
|
||||
(fp_line (start -8.89 1.27) (end -8.89 34.29) (layer F.CrtYd) (width 0.12))
|
||||
(fp_line (start -13.97 1.27) (end -8.89 1.27) (layer F.CrtYd) (width 0.12))
|
||||
(fp_line (start 8.89 34.29) (end 8.89 1.27) (layer F.CrtYd) (width 0.12))
|
||||
(fp_line (start 13.97 34.29) (end 8.89 34.29) (layer F.CrtYd) (width 0.12))
|
||||
(fp_line (start 13.97 1.27) (end 13.97 34.29) (layer F.CrtYd) (width 0.12))
|
||||
(fp_line (start 8.89 1.27) (end 13.97 1.27) (layer F.CrtYd) (width 0.12))
|
||||
(pad 2.3 thru_hole circle (at -12.7 5.08) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.4 thru_hole circle (at -10.16 5.08) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.5 thru_hole circle (at -12.7 7.62) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.6 thru_hole circle (at -10.16 7.62) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.7 thru_hole circle (at -12.7 10.16) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.8 thru_hole circle (at -10.16 10.16) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.9 thru_hole circle (at -12.7 12.7) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.10 thru_hole circle (at -10.16 12.7) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.11 thru_hole circle (at -12.7 15.24) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.12 thru_hole circle (at -10.16 15.24) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.13 thru_hole circle (at -12.7 17.78) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.14 thru_hole circle (at -10.16 17.78) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.15 thru_hole circle (at -12.7 20.32) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.16 thru_hole circle (at -10.16 20.32) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.17 thru_hole circle (at -12.7 22.86) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.18 thru_hole circle (at -10.16 22.86) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.19 thru_hole circle (at -12.7 25.4) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.20 thru_hole circle (at -10.16 25.4) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.21 thru_hole circle (at -12.7 27.94) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.22 thru_hole circle (at -10.16 27.94) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.23 thru_hole circle (at -12.7 30.48) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.24 thru_hole circle (at -10.16 30.48) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.25 thru_hole circle (at -12.7 33.02) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.26 thru_hole circle (at -10.16 33.02) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.1 thru_hole rect (at 10.16 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.2 thru_hole circle (at 12.7 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.3 thru_hole circle (at 10.16 5.08) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.4 thru_hole circle (at 12.7 5.08) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.5 thru_hole circle (at 10.16 7.62) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.6 thru_hole circle (at 12.7 7.62) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.7 thru_hole circle (at 10.16 10.16) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.8 thru_hole circle (at 12.7 10.16) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.9 thru_hole circle (at 10.16 12.7) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.10 thru_hole circle (at 12.7 12.7) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.11 thru_hole circle (at 10.16 15.24) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.12 thru_hole circle (at 12.7 15.24) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.13 thru_hole circle (at 10.16 17.78) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.14 thru_hole circle (at 12.7 17.78) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.15 thru_hole circle (at 10.16 20.32) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.16 thru_hole circle (at 12.7 20.32) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.17 thru_hole circle (at 10.16 22.86) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.18 thru_hole circle (at 12.7 22.86) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.19 thru_hole circle (at 10.16 25.4) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.20 thru_hole circle (at 12.7 25.4) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.21 thru_hole circle (at 10.16 27.94) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.22 thru_hole circle (at 12.7 27.94) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.23 thru_hole circle (at 10.16 30.48) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.24 thru_hole circle (at 12.7 30.48) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.25 thru_hole circle (at 10.16 33.02) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 3.26 thru_hole circle (at 12.7 33.02) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.1 thru_hole rect (at -12.7 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
(pad 2.2 thru_hole circle (at -10.16 2.54) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask))
|
||||
)
|
|
@ -0,0 +1,36 @@
|
|||
(footprint "Ferritbead_0603_1608Metric" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 61367F9E)
|
||||
(descr "Resistor SMD 0603 (1608 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: IPC-SM-782 page 72, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf), generated with kicad-footprint-generator")
|
||||
(tags "resistor")
|
||||
(attr smd)
|
||||
(fp_text reference "REF**" (at 0 -1.43) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 1ce2ffb7-ffc4-4e47-b214-2d2cac3c163f)
|
||||
)
|
||||
(fp_text value "Ferritbead_0603_1608Metric" (at -0.04 1.77) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 1aa798ef-05b4-4b6b-8a42-14d04b18e64b)
|
||||
)
|
||||
(fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab")
|
||||
(effects (font (size 0.4 0.4) (thickness 0.06)))
|
||||
(tstamp 786859eb-3872-47d1-b0a8-5c8bf5b59caa)
|
||||
)
|
||||
(fp_line (start -0.237258 -0.5225) (end 0.237258 -0.5225) (layer "F.SilkS") (width 0.12) (tstamp 70af1960-c7b2-47e7-bb4f-fabc79c69252))
|
||||
(fp_line (start -0.237258 0.5225) (end 0.237258 0.5225) (layer "F.SilkS") (width 0.12) (tstamp ff4b255d-3f6d-4a63-a192-65268a0eae13))
|
||||
(fp_line (start 1.48 -0.73) (end 1.48 0.73) (layer "F.CrtYd") (width 0.05) (tstamp 2a01c873-f57d-492e-bf25-58fe94e9d1e0))
|
||||
(fp_line (start -1.48 0.73) (end -1.48 -0.73) (layer "F.CrtYd") (width 0.05) (tstamp 5433ec0a-0a00-47bb-aad6-1c489b00e5eb))
|
||||
(fp_line (start -1.48 -0.73) (end 1.48 -0.73) (layer "F.CrtYd") (width 0.05) (tstamp b4839cf7-915f-4c3a-9fec-7fedef1a70be))
|
||||
(fp_line (start 1.48 0.73) (end -1.48 0.73) (layer "F.CrtYd") (width 0.05) (tstamp e9c83f62-8e46-4552-976d-19d79f6a16bc))
|
||||
(fp_line (start -0.8 -0.4125) (end 0.8 -0.4125) (layer "F.Fab") (width 0.1) (tstamp 6ee555d4-685b-4a36-a65d-b23477664fb4))
|
||||
(fp_line (start 0.8 -0.4125) (end 0.8 0.4125) (layer "F.Fab") (width 0.1) (tstamp a7708b89-613f-4f36-b3fc-95f809398e8c))
|
||||
(fp_line (start 0.8 0.4125) (end -0.8 0.4125) (layer "F.Fab") (width 0.1) (tstamp aa16870e-ed3b-4d28-b416-757f77673a2e))
|
||||
(fp_line (start -0.8 0.4125) (end -0.8 -0.4125) (layer "F.Fab") (width 0.1) (tstamp af57c83d-df74-4689-9e5f-264d28357c24))
|
||||
(pad "1" smd roundrect (at -0.825 0) (size 0.8 0.95) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 1e17f6de-84b5-47ae-a626-24dc38f0554e))
|
||||
(pad "2" smd roundrect (at 0.825 0) (size 0.8 0.95) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp d5a5a7f5-3c80-45cd-a86a-2699afb1d2f6))
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/Ferriit bead-0603.step"
|
||||
(offset (xyz 0 -0.25 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
|
@ -0,0 +1,115 @@
|
|||
(footprint "ICE40UP5K-SG48ITRQFN-48QFN" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 616F37D0)
|
||||
(descr "QFN, 48 Pin (http://www.st.com/resource/en/datasheet/stm32f042k6.pdf#page=94), generated with kicad-footprint-generator ipc_noLead_generator.py")
|
||||
(tags "QFN NoLead")
|
||||
(attr smd)
|
||||
(fp_text reference "REF**" (at 0 -4.82) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 612d3026-9be4-47d3-9f7e-79566d651b8c)
|
||||
)
|
||||
(fp_text value "ICE40UP5K-SG48ITRQFN-48" (at 0 4.82) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 233fb020-8d0e-4587-b6fd-49863319a31c)
|
||||
)
|
||||
(fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 9abe78e8-cd02-4892-b378-4098c4083479)
|
||||
)
|
||||
(fp_line (start 3.135 3.61) (end 3.61 3.61) (layer "F.SilkS") (width 0.12) (tstamp 1c154bd3-21fe-4ae7-9d38-138df617c625))
|
||||
(fp_line (start 3.135 -3.61) (end 3.61 -3.61) (layer "F.SilkS") (width 0.12) (tstamp 48022127-c694-4340-80a6-60b3d5340af7))
|
||||
(fp_line (start -3.135 -3.61) (end -3.61 -3.61) (layer "F.SilkS") (width 0.12) (tstamp 5a2e5d6a-fae6-4cda-b43c-f03b0ac47412))
|
||||
(fp_line (start -3.61 3.61) (end -3.61 3.135) (layer "F.SilkS") (width 0.12) (tstamp aeb3689a-92ec-4bc5-a749-8a78707ae63e))
|
||||
(fp_line (start 3.61 -3.61) (end 3.61 -3.135) (layer "F.SilkS") (width 0.12) (tstamp b0b97b4a-9cdf-4481-bf30-f78edaf9300a))
|
||||
(fp_line (start -3.135 3.61) (end -3.61 3.61) (layer "F.SilkS") (width 0.12) (tstamp d2140b97-3ed8-4348-b277-02841d1baecc))
|
||||
(fp_line (start 3.61 3.61) (end 3.61 3.135) (layer "F.SilkS") (width 0.12) (tstamp de5d727c-8e49-454f-97e0-39a6212ad06f))
|
||||
(fp_line (start 4.12 -4.12) (end -4.12 -4.12) (layer "F.CrtYd") (width 0.05) (tstamp 1faea7e2-782e-4cbb-87d8-851452b8a697))
|
||||
(fp_line (start -4.12 4.12) (end 4.12 4.12) (layer "F.CrtYd") (width 0.05) (tstamp 31a2fde1-c811-4054-b9e9-dd278be046a1))
|
||||
(fp_line (start -4.12 -4.12) (end -4.12 4.12) (layer "F.CrtYd") (width 0.05) (tstamp 5e72aa8b-ac6e-4319-9271-0e62fed8055b))
|
||||
(fp_line (start 4.12 4.12) (end 4.12 -4.12) (layer "F.CrtYd") (width 0.05) (tstamp 975354fe-8c32-44ac-8139-97f01f3c2fb9))
|
||||
(fp_line (start 3.5 3.5) (end -3.5 3.5) (layer "F.Fab") (width 0.1) (tstamp 0c7c6a1c-0b48-4b90-91eb-5d85c02062bd))
|
||||
(fp_line (start -3.5 3.5) (end -3.5 -2.5) (layer "F.Fab") (width 0.1) (tstamp 36d15b3a-8621-45c5-a111-a43531896fb1))
|
||||
(fp_line (start 3.5 -3.5) (end 3.5 3.5) (layer "F.Fab") (width 0.1) (tstamp 4e2cbe99-69bc-452b-a8b5-bcd716ef8994))
|
||||
(fp_line (start -3.5 -2.5) (end -2.5 -3.5) (layer "F.Fab") (width 0.1) (tstamp 73ed5572-4501-4247-9671-397eeb753d88))
|
||||
(fp_line (start -2.5 -3.5) (end 3.5 -3.5) (layer "F.Fab") (width 0.1) (tstamp de2f46c5-bacc-4864-90c6-f6cf715b693b))
|
||||
(pad "" smd roundrect (at -2.1 2.1) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp 111acb24-8fc7-4335-afac-cdae01c8fa5b))
|
||||
(pad "" smd roundrect (at -0.7 2.1) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp 15c61562-3b50-4729-9e30-a2d51ba08c48))
|
||||
(pad "" smd roundrect (at 2.1 2.1) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp 1610f979-9f30-4701-908f-2ab18ff38c4e))
|
||||
(pad "" smd roundrect (at 0.7 0.7) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp 1b53423c-aa60-4168-bf2f-bdedd5015dbe))
|
||||
(pad "" smd roundrect (at -2.1 -0.7) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp 3167ec41-f663-40e2-bfc9-3f9ded6d5f24))
|
||||
(pad "" smd roundrect (at 0.7 -0.7) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp 72da1521-ab8e-43e4-a5a1-6c1232aa1523))
|
||||
(pad "" smd roundrect (at -0.7 -2.1) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp ad6ef228-0a1d-4722-8082-42dd79ffd2c1))
|
||||
(pad "" smd roundrect (at -0.7 -0.7) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp b8d5e78f-1b32-4d38-9780-fc78320fb05c))
|
||||
(pad "" smd roundrect (at -2.1 -2.1) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp c3ca7fe3-4be1-4f1c-8523-bedfd0a320a6))
|
||||
(pad "" smd roundrect (at 0.7 2.1) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp d37fb919-08c3-49ff-a49f-5698cc7b15c9))
|
||||
(pad "" smd roundrect (at -2.1 0.7) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp d38d75a5-f578-4f5b-b121-77f4f1284136))
|
||||
(pad "" smd roundrect (at -0.7 0.7) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp d8b0eb33-286f-48ea-b1c8-683133497e9d))
|
||||
(pad "" smd roundrect (at 2.1 -2.1) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp de096609-eeb1-49f2-81b5-d9da9f7246bf))
|
||||
(pad "" smd roundrect (at 2.1 0.7) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp e01533bb-8c98-437b-a0c8-4bd8f3319120))
|
||||
(pad "" smd roundrect (at 0.7 -2.1) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp f8e19c9f-b06a-40a9-801e-f0c9c9eab231))
|
||||
(pad "" smd roundrect (at 2.1 -0.7) (size 1.13 1.13) (layers "F.Paste") (roundrect_rratio 0.221239) (tstamp fbd779dd-6c19-405f-bf84-2db8decaac68))
|
||||
(pad "1" smd roundrect (at -3.4375 -2.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 47f2cf27-9943-4644-a23d-bf57dcef64e4))
|
||||
(pad "2" smd roundrect (at -3.4375 -2.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 538be93e-9d02-4c44-b797-27b4d4e0a3b0))
|
||||
(pad "3" smd roundrect (at -3.4375 -1.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 39fb6573-307d-4b18-b800-eebc0cb49538))
|
||||
(pad "4" smd roundrect (at -3.4375 -1.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp e561dfa8-0b32-4cb2-b7dc-7df974b52e9e))
|
||||
(pad "5" smd roundrect (at -3.4375 -0.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 27020de1-e7d9-4caf-8f64-8ca0900a9c53))
|
||||
(pad "6" smd roundrect (at -3.4375 -0.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 60abf821-b8ae-456a-9946-e8456d2d2228))
|
||||
(pad "7" smd roundrect (at -3.4375 0.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 81fe3798-d664-412c-8752-f07fa912e9f1))
|
||||
(pad "8" smd roundrect (at -3.4375 0.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp fc52d54d-1c86-4529-b159-0ef074b57360))
|
||||
(pad "9" smd roundrect (at -3.4375 1.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp ca5ed947-9774-488a-bf67-43369f1f3b56))
|
||||
(pad "10" smd roundrect (at -3.4375 1.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp d8edbcae-64fa-4843-9ed4-ebc6f4001489))
|
||||
(pad "11" smd roundrect (at -3.4375 2.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 164c910d-4aab-476a-82b4-327fb3aec257))
|
||||
(pad "12" smd roundrect (at -3.4375 2.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp d262079b-9105-4efa-b3eb-12df6c97a0b7))
|
||||
(pad "13" smd roundrect (at -2.75 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp edb5da08-7c04-4ad4-9a40-5201f7bdf31c))
|
||||
(pad "14" smd roundrect (at -2.25 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp bee823cd-6d90-4ff8-b111-cfb18110db66))
|
||||
(pad "15" smd roundrect (at -1.75 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 6745996f-203e-41ea-951c-b7abd96f894d))
|
||||
(pad "16" smd roundrect (at -1.25 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 4cb91b14-51da-4655-9a84-7a0b0e03242f))
|
||||
(pad "17" smd roundrect (at -0.75 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp a9afa0b4-07b7-4da0-bcaf-8e02d831b979))
|
||||
(pad "18" smd roundrect (at -0.25 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp ba61efbe-c0c7-49c0-8e76-a656312b40c6))
|
||||
(pad "19" smd roundrect (at 0.25 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp d2143b61-ca12-480b-ad56-9f7a5c4cfe87))
|
||||
(pad "20" smd roundrect (at 0.75 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp a7dee156-9cb7-4378-88c2-445b299bdb4b))
|
||||
(pad "21" smd roundrect (at 1.25 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp c83ec62d-7104-433d-a64a-6e3c06fa8f02))
|
||||
(pad "22" smd roundrect (at 1.75 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp d2f6c0ae-93ea-490c-a0d3-bb3c10f0310e))
|
||||
(pad "23" smd roundrect (at 2.25 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp f482f350-a5ad-43b8-9ec2-07fb6ee67689))
|
||||
(pad "24" smd roundrect (at 2.75 3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 60ecae3f-2c75-4c7e-9e18-f686bb3a2db6))
|
||||
(pad "25" smd roundrect (at 3.4375 2.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp afa8d13b-8daf-42a0-af71-47acad988704))
|
||||
(pad "26" smd roundrect (at 3.4375 2.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 28438be6-1a26-48a6-93b8-4cc2add285e7))
|
||||
(pad "27" smd roundrect (at 3.4375 1.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp d6b18d30-d5e9-4a1f-af52-e5a616b08474))
|
||||
(pad "28" smd roundrect (at 3.4375 1.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 7a86f46c-3bc1-4456-8bf7-12cfd5924db3))
|
||||
(pad "29" smd roundrect (at 3.4375 0.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 0216661e-f2bf-4d54-b3dc-9e643965a716))
|
||||
(pad "30" smd roundrect (at 3.4375 0.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 6b57972f-40aa-45b2-b0b5-a3d39555f242))
|
||||
(pad "31" smd roundrect (at 3.4375 -0.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 4c3624f0-e956-409d-9861-fe09d492f3fe))
|
||||
(pad "32" smd roundrect (at 3.4375 -0.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp b987f42a-6a83-4674-9036-886e9a714c50))
|
||||
(pad "33" smd roundrect (at 3.4375 -1.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 0cb8ea63-c770-4231-9d50-f32c9e8d05b8))
|
||||
(pad "34" smd roundrect (at 3.4375 -1.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 44ed9385-2164-48d7-bb89-8d1ead808a7f))
|
||||
(pad "35" smd roundrect (at 3.4375 -2.25) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 48ad2275-533d-4e01-8ade-40a33d46b849))
|
||||
(pad "36" smd roundrect (at 3.4375 -2.75) (size 0.875 0.25) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 04721b2a-b8fe-4628-b3cc-831c2dbc8b4f))
|
||||
(pad "37" smd roundrect (at 2.75 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 2b6f8022-7144-45f1-8a7a-80a4246a5dc3))
|
||||
(pad "38" smd roundrect (at 2.25 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 61267833-1866-4c57-8b4f-6466ea9dfc6e))
|
||||
(pad "39" smd roundrect (at 1.75 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 14c8c762-b037-4a8c-85d3-f06a98ef03f4))
|
||||
(pad "40" smd roundrect (at 1.25 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp d2fde1c5-c4fa-48e6-a672-a3a232389978))
|
||||
(pad "41" smd roundrect (at 0.75 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 91b0ff9a-a35c-4fec-89cf-75f03e9ac5f6))
|
||||
(pad "42" smd roundrect (at 0.25 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 20266038-f6fa-4d8d-b2d5-71fd57c6017d))
|
||||
(pad "43" smd roundrect (at -0.25 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp f030bb2e-b46d-495b-8275-d4c56529e711))
|
||||
(pad "44" smd roundrect (at -0.75 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 9ff0c804-5671-445d-be22-c4acb3a87f27))
|
||||
(pad "45" smd roundrect (at -1.25 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 96de58ae-bd0c-4729-bcaa-2c880345f3be))
|
||||
(pad "46" smd roundrect (at -1.75 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp dc2ab6b2-cd86-4474-b773-229cca8c149d))
|
||||
(pad "47" smd roundrect (at -2.25 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp db934191-c8cd-46af-9c49-bfde6495955e))
|
||||
(pad "48" smd roundrect (at -2.75 -3.4375) (size 0.25 0.875) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 5412c2c5-a98d-4490-b76b-96cd21ed9b30))
|
||||
(pad "49" smd rect (at 0 0) (size 5.5 5.5) (layers "F.Cu" "F.Mask") (tstamp 1ce64a03-ad4d-44d3-ac8c-71661f3f2b1f))
|
||||
(pad "49" thru_hole circle (at 1.524 -1.524 270) (size 0.6 0.6) (drill 0.3) (layers *.Cu *.Mask)
|
||||
(solder_mask_margin -0.299) (zone_connect 2) (tstamp 2ae1c526-ad04-407b-ab02-84fa363edb82))
|
||||
(pad "49" thru_hole circle (at 0 0 270) (size 0.6 0.6) (drill 0.3) (layers *.Cu *.Mask)
|
||||
(solder_mask_margin -0.299) (zone_connect 2) (tstamp 469df793-f33d-41cd-9b5c-00ed8cee8c14))
|
||||
(pad "49" thru_hole circle (at -1.524 -1.524) (size 0.6 0.6) (drill 0.3) (layers *.Cu *.Mask)
|
||||
(solder_mask_margin -0.299) (zone_connect 2) (tstamp 9f2e1f61-0a01-4d05-83f5-3f74a884faa3))
|
||||
(pad "49" thru_hole circle (at 1.524 1.524 180) (size 0.6 0.6) (drill 0.3) (layers *.Cu *.Mask)
|
||||
(solder_mask_margin -0.299) (zone_connect 2) (tstamp bc412c42-be50-43b8-8c75-cd975fbb3ca5))
|
||||
(pad "49" thru_hole circle (at -1.524 1.524 90) (size 0.6 0.6) (drill 0.3) (layers *.Cu *.Mask)
|
||||
(solder_mask_margin -0.299) (zone_connect 2) (tstamp e9ad732c-39a0-4f85-bb64-c1634a3ecf95))
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/ICE40UP5K-SG48ITR.step"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz -90 0 90))
|
||||
)
|
||||
)
|
31
hw/boards/mta1-library/mta1.pretty/MC2016Z.kicad_mod
Normal file
31
hw/boards/mta1-library/mta1.pretty/MC2016Z.kicad_mod
Normal file
|
@ -0,0 +1,31 @@
|
|||
(footprint "MC2016Z" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 616D9B54)
|
||||
(attr smd)
|
||||
(fp_text reference "REF**" (at 0 -2.54) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 70287de0-48a5-4423-9df4-b3637a983995)
|
||||
)
|
||||
(fp_text value "MC2016Z" (at 0 2.54) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 3ecc3ee0-902e-4f65-a588-ddb47ef0a3d0)
|
||||
)
|
||||
(fp_line (start -1.3 -1.1) (end -1.3 1.1) (layer "F.CrtYd") (width 0.05) (tstamp 042359c4-6b3f-4fe2-924f-73a4f515f170))
|
||||
(fp_line (start 1.3 -1.1) (end 1.3 1.1) (layer "F.CrtYd") (width 0.05) (tstamp 21b67917-58a7-447c-a784-88ee29113dd8))
|
||||
(fp_line (start 1.3 1.1) (end -1.3 1.1) (layer "F.CrtYd") (width 0.05) (tstamp 429f300a-5a92-4aca-a9e6-ea0cb6ea6035))
|
||||
(fp_line (start -1.3 -1.1) (end 1.3 -1.1) (layer "F.CrtYd") (width 0.05) (tstamp ff9343d4-84f2-4396-9e02-04aaa31bdb53))
|
||||
(fp_line (start -1 0.5) (end -1 -0.8) (layer "F.Fab") (width 0.1) (tstamp 5e8d0296-968d-40e7-872d-ccc1afa29217))
|
||||
(fp_line (start 1 -0.8) (end 1 0.8) (layer "F.Fab") (width 0.1) (tstamp 8a39c6fb-adfe-4cb7-a8fd-aa0789c3fa29))
|
||||
(fp_line (start -1 0.5) (end -0.7 0.8) (layer "F.Fab") (width 0.1) (tstamp 8e7e2e4c-b30d-4926-beb7-1b6630ee1e61))
|
||||
(fp_line (start 1 0.8) (end -0.7 0.8) (layer "F.Fab") (width 0.1) (tstamp b06d4c22-a2d3-45a6-8b86-b3abdc291afe))
|
||||
(fp_line (start -1 -0.8) (end 1 -0.8) (layer "F.Fab") (width 0.1) (tstamp e84ca0fc-9f31-465b-abfa-053f521021f5))
|
||||
(pad "1" smd rect (at -0.9 0.6) (size 0.6 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp c435196e-d561-4fbb-bac7-9de7ee23985f))
|
||||
(pad "2" smd rect (at 0.9 0.6) (size 0.6 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp d8897cf8-97c4-48be-a51a-ab1c528c9275))
|
||||
(pad "3" smd rect (at 0.9 -0.6) (size 0.6 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 39d2c8c1-582d-455e-a286-2c0562871862))
|
||||
(pad "4" smd rect (at -0.9 -0.6) (size 0.6 0.8) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 16ddb3da-3aaf-4c5f-8323-3c95c55ac2ae))
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/MC2016Z.step"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz -90 0 0))
|
||||
)
|
||||
)
|
|
@ -0,0 +1,40 @@
|
|||
(footprint "MCP1824T-SOT-23-5" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 61367FF8)
|
||||
(descr "5-pin SOT23 package")
|
||||
(tags "SOT-23-5")
|
||||
(attr smd)
|
||||
(fp_text reference "REF**" (at 0 -2.9) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp a17d7f86-0179-400a-95d2-ed0f6cd17a49)
|
||||
)
|
||||
(fp_text value "MCP1824T-SOT-23-5" (at 0 2.9) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp a3f544d4-dd21-44ac-8509-674521c3bf4a)
|
||||
)
|
||||
(fp_text user "${REFERENCE}" (at 0 0 90) (layer "F.Fab")
|
||||
(effects (font (size 0.5 0.5) (thickness 0.075)))
|
||||
(tstamp 4507dadf-eb27-4a89-8b5f-c0830610c77e)
|
||||
)
|
||||
(fp_line (start -0.9 1.61) (end 0.9 1.61) (layer "F.SilkS") (width 0.12) (tstamp 96f5d14b-4279-4869-a4d9-89b9ba5b9326))
|
||||
(fp_line (start 0.9 -1.61) (end -1.55 -1.61) (layer "F.SilkS") (width 0.12) (tstamp fa031bdf-5e99-42dc-8692-15c30e685b5a))
|
||||
(fp_line (start -1.9 -1.8) (end 1.9 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 3676d1ad-dfe9-41bb-9b6c-e14d93943fa2))
|
||||
(fp_line (start -1.9 1.8) (end -1.9 -1.8) (layer "F.CrtYd") (width 0.05) (tstamp 6acb4a6c-b1db-42c8-a925-721926fe18af))
|
||||
(fp_line (start 1.9 -1.8) (end 1.9 1.8) (layer "F.CrtYd") (width 0.05) (tstamp af5efa2f-594c-4cd5-abf4-97bbd8a484a5))
|
||||
(fp_line (start 1.9 1.8) (end -1.9 1.8) (layer "F.CrtYd") (width 0.05) (tstamp b3fd0d04-2d8b-42a2-8f69-962c14297589))
|
||||
(fp_line (start 0.9 1.55) (end -0.9 1.55) (layer "F.Fab") (width 0.1) (tstamp 344cca83-1ca2-4f3a-9033-74708f6f273d))
|
||||
(fp_line (start -0.9 -0.9) (end -0.25 -1.55) (layer "F.Fab") (width 0.1) (tstamp 7c1dcaa1-0b4e-40e0-964d-fd434e8d90c2))
|
||||
(fp_line (start 0.9 -1.55) (end -0.25 -1.55) (layer "F.Fab") (width 0.1) (tstamp 810546bb-88ef-4798-bd6a-845f73a2a903))
|
||||
(fp_line (start -0.9 -0.9) (end -0.9 1.55) (layer "F.Fab") (width 0.1) (tstamp a0876043-d1a0-43c6-832a-933a920ea949))
|
||||
(fp_line (start 0.9 -1.55) (end 0.9 1.55) (layer "F.Fab") (width 0.1) (tstamp f009fb07-369f-4627-ae7e-c463dbea31d6))
|
||||
(pad "1" smd rect (at -1.1 -0.95) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 5be42e98-179d-467f-b08d-4146ced5e7eb))
|
||||
(pad "2" smd rect (at -1.1 0) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp bd932edf-7fdc-4b44-8578-1f565b0464cc))
|
||||
(pad "3" smd rect (at -1.1 0.95) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 9db2a5e9-1bf3-44eb-b6b7-29b31eed868d))
|
||||
(pad "4" smd rect (at 1.1 0.95) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 1e24719a-bb94-4cfb-822d-1c2b0bd38b64))
|
||||
(pad "5" smd rect (at 1.1 -0.95) (size 1.06 0.65) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 08dbfb9c-6164-4cf0-af58-fa4477606202))
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/MCP1824T.step"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz -90 0 -90))
|
||||
)
|
||||
)
|
34
hw/boards/mta1-library/mta1.pretty/NCP752BSN33T1G.kicad_mod
Normal file
34
hw/boards/mta1-library/mta1.pretty/NCP752BSN33T1G.kicad_mod
Normal file
|
@ -0,0 +1,34 @@
|
|||
(footprint "NCP752BSN33T1G" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 616ECE40)
|
||||
(attr smd)
|
||||
(fp_text reference "REF**" (at 0 -3.81) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp ea5a20bb-c640-47a9-806f-cebd20350c6e)
|
||||
)
|
||||
(fp_text value "NCP752BSN33T1G" (at 0 3.81) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 68f3b860-6277-4b0a-881d-06899522ea17)
|
||||
)
|
||||
(fp_line (start -0.9 1.61) (end 0.9 1.61) (layer "F.SilkS") (width 0.12) (tstamp 6e5cefcf-65ad-4263-b0f7-e81767e10695))
|
||||
(fp_line (start 0.9 -1.61) (end -1.55 -1.61) (layer "F.SilkS") (width 0.12) (tstamp e95f7615-6547-498d-94da-56b2857a02ea))
|
||||
(fp_line (start 1.9 -1.5) (end 1.9 1.5) (layer "F.CrtYd") (width 0.05) (tstamp 61c34542-af3e-42b6-b288-c86e516c35ea))
|
||||
(fp_line (start -1.9 -1.5) (end 1.9 -1.5) (layer "F.CrtYd") (width 0.05) (tstamp 9548cf5b-a09a-4505-894a-a92b90eefa07))
|
||||
(fp_line (start -1.9 1.5) (end -1.9 -1.5) (layer "F.CrtYd") (width 0.05) (tstamp a7ade3c5-1d11-4e28-9c66-d7a3210fe984))
|
||||
(fp_line (start 1.9 1.5) (end -1.9 1.5) (layer "F.CrtYd") (width 0.05) (tstamp cea10542-7924-4256-bef1-d9e9c146e1f5))
|
||||
(fp_line (start -0.825 1.575) (end -0.825 -1.2) (layer "F.Fab") (width 0.12) (tstamp 856fa11c-f489-4642-99c6-d2369520cc75))
|
||||
(fp_line (start -0.5 -1.575) (end 0.825 -1.575) (layer "F.Fab") (width 0.12) (tstamp 8a15ba15-f0c9-4c69-b0c7-f497dae6fff5))
|
||||
(fp_line (start 0.825 -1.575) (end 0.825 1.575) (layer "F.Fab") (width 0.12) (tstamp aab352ee-93c2-4186-9af0-a86a8c96089a))
|
||||
(fp_line (start 0.825 1.575) (end -0.825 1.575) (layer "F.Fab") (width 0.1) (tstamp d8648659-e0f3-4371-b3af-4ff643c2b44e))
|
||||
(fp_line (start -0.5 -1.575) (end -0.825 -1.2) (layer "F.Fab") (width 0.12) (tstamp f5d5f9c7-cd53-432e-87df-bf2dacc807c7))
|
||||
(pad "1" smd rect (at -1.2 -0.95 270) (size 0.7 1) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp ea245e44-4956-45b1-b440-bef9b1d8a885))
|
||||
(pad "2" smd rect (at -1.2 0 270) (size 0.7 1) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 86cdc1d7-fdb3-4ffc-9f6f-cf5282c31d3b))
|
||||
(pad "3" smd rect (at -1.2 0.95 270) (size 0.7 1) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 5bff8781-6551-4141-995b-343fb5aa90ae))
|
||||
(pad "4" smd rect (at 1.2 0.95 270) (size 0.7 1) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 59005e90-31b3-4c2d-b870-1409713c62cf))
|
||||
(pad "5" smd rect (at 1.2 -0.95 270) (size 0.7 1) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 28707e0a-dd24-4294-bf8c-5773a9252ade))
|
||||
(model "${KICAD6_3DMODEL_DIR}/Package_TO_SOT_SMD.3dshapes/TSOT-23-5.wrl"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
|
@ -0,0 +1,68 @@
|
|||
(module PinHeader_1x06_P2.54mm_Horizontal (layer F.Cu) (tedit 6137807A)
|
||||
(descr "Through hole angled pin header, 1x06, 2.54mm pitch, 6mm pin length, single row")
|
||||
(tags "Through hole angled pin header THT 1x06 2.54mm single row")
|
||||
(fp_text reference J (at -4.385 14.97) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value PMOD-Device-x1-Type-2-SPI (at 4.385 14.97 180) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_line (start -1.524 13.97) (end -4.04 13.97) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 13.97) (end -4.04 -1.27) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 -1.27) (end -1.5 -1.27) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1.5 -1.27) (end -1.524 13.97) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 13.02) (end -1.5 13.02) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 13.02) (end 0.32 12.38) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 12.38) (end -1.5 12.38) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 13.02) (end -10.04 13.02) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -10.04 13.02) (end -10.04 12.38) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 12.38) (end -10.04 12.38) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 10.48) (end -1.5 10.48) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 10.48) (end 0.32 9.84) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 9.84) (end -1.5 9.84) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 10.48) (end -10.04 10.48) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -10.04 10.48) (end -10.04 9.84) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 9.84) (end -10.04 9.84) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 7.94) (end -1.5 7.94) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 7.94) (end 0.32 7.3) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 7.3) (end -1.5 7.3) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 7.94) (end -10.04 7.94) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -10.04 7.94) (end -10.04 7.3) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 7.3) (end -10.04 7.3) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 5.4) (end -1.5 5.4) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 5.4) (end 0.32 4.76) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 4.76) (end -1.5 4.76) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 5.4) (end -10.04 5.4) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -10.04 5.4) (end -10.04 4.76) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 4.76) (end -10.04 4.76) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 2.86) (end -1.5 2.86) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 2.86) (end 0.32 2.22) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 2.22) (end -1.5 2.22) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 2.86) (end -10.04 2.86) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -10.04 2.86) (end -10.04 2.22) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 2.22) (end -10.04 2.22) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 0.32) (end -1.5 0.32) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 0.32) (end 0.32 -0.32) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 0.32 -0.32) (end -1.5 -0.32) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 0.32) (end -10.04 0.32) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -10.04 0.32) (end -10.04 -0.32) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -4.04 -0.32) (end -10.04 -0.32) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 1.8 14.5) (end 1.8 -1.8) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.8 -1.8) (end -10.55 -1.8) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -10.55 -1.8) (end -10.55 14.5) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -10.55 14.5) (end 1.8 14.5) (layer F.CrtYd) (width 0.05))
|
||||
(fp_text user %R (at -2.77 6.35 270) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(pad 6 thru_hole oval (at 0 12.7) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
|
||||
(pad 5 thru_hole oval (at 0 10.16) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
|
||||
(pad 4 thru_hole oval (at 0 7.62) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
|
||||
(pad 3 thru_hole oval (at 0 5.08) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
|
||||
(pad 2 thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
|
||||
(pad 1 thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
|
||||
(model ${KICAD6_3DMODEL_DIR}/Connector_PinHeader_2.54mm.3dshapes/PinHeader_1x06_P2.54mm_Horizontal.wrl
|
||||
(offset (xyz 0 -12.7 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 180))
|
||||
)
|
||||
)
|
70
hw/boards/mta1-library/mta1.pretty/U261-241N-4BS60.kicad_mod
Normal file
70
hw/boards/mta1-library/mta1.pretty/U261-241N-4BS60.kicad_mod
Normal file
|
@ -0,0 +1,70 @@
|
|||
(footprint "U261-241N-4BS60" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 0)
|
||||
(attr smd)
|
||||
(fp_text reference "p**" (at 0 6 unlocked) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp a5909492-b68b-47b5-b3df-4a73813624d6)
|
||||
)
|
||||
(fp_text value "U261-241N-4BS60" (at 0 7.5 unlocked) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 19e90bfe-f65f-43c6-9cdd-8c125d76e597)
|
||||
)
|
||||
(fp_text user "${REFERENCE}" (at 0 9 unlocked) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 197d02fb-97b2-4f49-8a55-7a7a2968ec81)
|
||||
)
|
||||
(fp_line (start -1.95 -3.05) (end -1.95 3.05) (layer "Edge.Cuts") (width 0.05) (tstamp 75dc6972-0628-4bc4-9a7e-d160b69fe920))
|
||||
(fp_line (start -1.95 3.05) (end -1.05 3.05) (layer "Edge.Cuts") (width 0.05) (tstamp 799d7ade-e82c-4a76-8037-81fef6257dcb))
|
||||
(fp_line (start -1.95 -3.05) (end -1.05 -3.05) (layer "Edge.Cuts") (width 0.05) (tstamp 8475e8e0-da24-483c-8120-57ca7be2f880))
|
||||
(fp_line (start -1.05 -3.05) (end -1.05 -3.95) (layer "Edge.Cuts") (width 0.05) (tstamp 88fe65e8-3e79-4518-9ef6-eb68c77d3692))
|
||||
(fp_line (start -1.05 3.95) (end -1.05 3.05) (layer "Edge.Cuts") (width 0.05) (tstamp b8ea1822-0523-420e-b160-af3693ed5f8f))
|
||||
(fp_line (start -1.95 -4.3) (end -1.95 4.3) (layer "B.CrtYd") (width 0.05) (tstamp 588dc4ea-9a5d-4ada-a7c3-466df9d61d7a))
|
||||
(fp_line (start -1.95 -4.3) (end 1 -4.3) (layer "B.CrtYd") (width 0.05) (tstamp 8f4ffa12-389c-41fc-b1d1-af983afce804))
|
||||
(fp_line (start 1 -4.3) (end 1 4.3) (layer "B.CrtYd") (width 0.05) (tstamp b55faf99-1682-40ee-989d-c918ee6c62ef))
|
||||
(fp_line (start -1.95 4.3) (end 1 4.3) (layer "B.CrtYd") (width 0.05) (tstamp bea2c15a-93a2-448f-82c3-1e6b1de5cb59))
|
||||
(fp_line (start 1 -4.3) (end -1.95 -4.3) (layer "F.CrtYd") (width 0.05) (tstamp 11e58d60-e236-42b4-aef7-1dca88420759))
|
||||
(fp_line (start 1 -4.3) (end 1 4.3) (layer "F.CrtYd") (width 0.05) (tstamp 85692491-c622-48d6-9dce-5c5016e3f16b))
|
||||
(fp_line (start -1.95 -4.3) (end -1.95 4.3) (layer "F.CrtYd") (width 0.05) (tstamp a3d8746d-e3e9-4814-8ec4-12f54a954b0f))
|
||||
(fp_line (start 1 4.3) (end -1.95 4.3) (layer "F.CrtYd") (width 0.05) (tstamp cbab0082-acb5-40a0-8ab7-982bded63078))
|
||||
(fp_line (start -1.9 4.3) (end -1.9 -4.3) (layer "F.Fab") (width 0.1) (tstamp 150b4643-ceae-41af-ad53-ecad8e9e3b00))
|
||||
(fp_line (start 1 -4.3) (end 1 4.3) (layer "F.Fab") (width 0.1) (tstamp 9dbb841f-4c91-44a1-9c07-88ecee83cb6e))
|
||||
(fp_line (start -1.9 -4.3) (end 1 -4.3) (layer "F.Fab") (width 0.1) (tstamp eab54c5d-c96e-4d10-92e8-6fa5e342690e))
|
||||
(fp_line (start -1.9 4.3) (end 1 4.3) (layer "F.Fab") (width 0.1) (tstamp f555cc33-a925-464f-aea8-9204ad392aef))
|
||||
(pad "A1" smd roundrect (at 0 2.75 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 575eac09-9ab4-4d4a-9adc-9f3c93e83df0))
|
||||
(pad "A2" smd roundrect (at 0 2.25 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 447af525-29cb-453a-83b3-010296d77606))
|
||||
(pad "A3" smd roundrect (at 0 1.75 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp e4879e73-8221-4170-9747-2ee77258af6a))
|
||||
(pad "A4" smd roundrect (at 0 1.25 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 29a38ecf-721f-4803-8717-644aa3b2b6c7))
|
||||
(pad "A5" smd roundrect (at 0 0.75 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 53fc9dda-b39b-44a3-a8b4-385576a79738))
|
||||
(pad "A6" smd roundrect (at 0 0.25 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 40b3c8f4-2216-4f8e-b568-fffa5ab5ee91))
|
||||
(pad "A7" smd roundrect (at 0 -0.25 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp a8a9a30f-c59e-496b-b53a-05d17656e790))
|
||||
(pad "A8" smd roundrect (at 0 -0.75 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp eaf6b8df-505d-4fef-852a-fb93bd407a4d))
|
||||
(pad "A9" smd roundrect (at 0 -1.25 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 84c7e2c4-207a-48f1-b57e-d697cac3f768))
|
||||
(pad "A10" smd roundrect (at 0 -1.75 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 6ba22cd4-0ca2-4a77-baea-ec880ce3f82a))
|
||||
(pad "A11" smd roundrect (at 0 -2.25 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp 64a5c7b4-43e4-43a2-93cd-6fe7b065c5f6))
|
||||
(pad "A12" smd roundrect (at 0 -2.75 180) (size 1.5 0.3) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp fbd7fec4-d679-4990-9537-8e72323dcb43))
|
||||
(pad "B1" smd roundrect (at 0 -2.75) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp f8b0e313-d41e-4f68-8089-5e8734adf468))
|
||||
(pad "B2" smd roundrect (at 0 -2.25) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp b2de0dba-0a59-46ec-ae11-4c4d86c7a834))
|
||||
(pad "B3" smd roundrect (at 0 -1.75) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 70245721-4384-45b4-bbfb-07eb5761e6e2))
|
||||
(pad "B4" smd roundrect (at 0 -1.25) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 53106c29-75a7-4fdb-8353-55e2a9d528e7))
|
||||
(pad "B5" smd roundrect (at 0 -0.75) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp db72467b-7152-4065-a40f-b5b1c3d36c43))
|
||||
(pad "B6" smd roundrect (at 0 -0.25) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp a5a2ebb3-626a-4851-92a0-f8d0a9945f60))
|
||||
(pad "B7" smd roundrect (at 0 0.25) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp e20a9065-3779-4fd2-962e-8c7fa0b0e077))
|
||||
(pad "B8" smd roundrect (at 0 0.75) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 16391464-719c-4a3b-beb1-04b9030b1554))
|
||||
(pad "B9" smd roundrect (at 0 1.25) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 4ce31103-ba55-4fb9-a0a4-7ef244e13e1f))
|
||||
(pad "B10" smd roundrect (at 0 1.75) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp f50302ae-1ce7-4f6c-b1b8-7853a92f3657))
|
||||
(pad "B11" smd roundrect (at 0 2.25) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp eb5aaf20-f26b-4f81-b5ce-a98e40989103))
|
||||
(pad "B12" smd roundrect (at 0 2.75) (size 1.5 0.3) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 99884a97-6523-44d5-91be-7a3b248f01e6))
|
||||
(pad "S1" smd roundrect (at 0.05 -3.5) (size 1.4 0.7) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) (tstamp 60440f32-5469-4b0a-9ea2-3d64cf4ec547))
|
||||
(pad "S1" smd roundrect (at 0.05 3.5 180) (size 1.4 0.7) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp cd07182f-59af-4d96-8ba6-c1baa50a5e83))
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/U261-241N-4BS60.step" hide
|
||||
(offset (xyz -1 0 -0.5))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 180 0 90))
|
||||
)
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/u261-24xn-4bs60.stp"
|
||||
(offset (xyz -11.5 0 -0.45))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz -90 0 90))
|
||||
)
|
||||
)
|
51
hw/boards/mta1-library/mta1.pretty/W25Q80DVUXIE.kicad_mod
Normal file
51
hw/boards/mta1-library/mta1.pretty/W25Q80DVUXIE.kicad_mod
Normal file
|
@ -0,0 +1,51 @@
|
|||
(footprint "W25Q80DVUXIE" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 0)
|
||||
(attr smd)
|
||||
(fp_text reference "REF**" (at 0 -2.54 unlocked) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 465137b4-f6f7-4d51-9b40-b161947d5cc1)
|
||||
)
|
||||
(fp_text value "W25Q80DVUXIE" (at 0 2.3 unlocked) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp d1cd5391-31d2-459f-8adb-4ae3f304a833)
|
||||
)
|
||||
(fp_text user "${REFERENCE}" (at 0 0 unlocked) (layer "F.Fab")
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
(tstamp 4086cbd7-6ba7-4e63-8da9-17e60627ee17)
|
||||
)
|
||||
(fp_rect (start -1.65 0.85) (end -1.1 0.65) (layer "F.Paste") (width 0) (fill solid) (tstamp 05fd22cb-dff4-4a8c-8f01-3428b502748b))
|
||||
(fp_rect (start -1.65 -0.15) (end -1.1 -0.35) (layer "F.Paste") (width 0) (fill solid) (tstamp 0810d445-1df3-46a9-896a-86ad16793678))
|
||||
(fp_rect (start 1.1 0.85) (end 1.65 0.65) (layer "F.Paste") (width 0) (fill solid) (tstamp 287ef878-3010-4032-8614-43b8c94551f4))
|
||||
(fp_rect (start 0.1 0.1) (end -0.1 0.6) (layer "F.Paste") (width 0) (fill solid) (tstamp 321442de-1be8-447c-864f-6a257a7c6538))
|
||||
(fp_rect (start -1.65 0.35) (end -1.1 0.15) (layer "F.Paste") (width 0) (fill solid) (tstamp c3b485fe-0f1e-46fb-b3ff-8782ddd819b9))
|
||||
(fp_rect (start 1.1 -0.65) (end 1.65 -0.85) (layer "F.Paste") (width 0) (fill solid) (tstamp ce513be5-314f-4c8a-b67c-995b4d660942))
|
||||
(fp_rect (start 1.1 0.35) (end 1.65 0.15) (layer "F.Paste") (width 0) (fill solid) (tstamp d5345ffb-e660-46fd-91a1-6d7002bcf227))
|
||||
(fp_rect (start 0.1 -0.6) (end -0.1 -0.1) (layer "F.Paste") (width 0) (fill solid) (tstamp db25ded8-11d6-4044-a831-59c0188314fb))
|
||||
(fp_rect (start 1.1 -0.15) (end 1.65 -0.35) (layer "F.Paste") (width 0) (fill solid) (tstamp fad25daf-d489-46ee-a7a9-e23c39213e36))
|
||||
(fp_rect (start -1.65 -0.65) (end -1.1 -0.85) (layer "F.Paste") (width 0) (fill solid) (tstamp fdbc71b1-4096-4d2c-99bc-b62ad2c2fdeb))
|
||||
(fp_line (start 0.7 1.1) (end -0.7 1.1) (layer "F.SilkS") (width 0.12) (tstamp 3036986f-780f-4e5b-8e4b-4e66acc1e072))
|
||||
(fp_line (start 0.7 -1.1) (end -1.225 -1.1) (layer "F.SilkS") (width 0.12) (tstamp 61e795c9-5bb5-48b3-b7a0-cb64f04c7adc))
|
||||
(fp_line (start -1.8 -1.3) (end 1.8 -1.3) (layer "F.CrtYd") (width 0.05) (tstamp 74af2938-5aa5-43d4-bb52-2d07b4b7e88e))
|
||||
(fp_line (start 1.8 1.3) (end -1.8 1.3) (layer "F.CrtYd") (width 0.05) (tstamp 773a22ae-c653-4f8d-930e-4149eabde637))
|
||||
(fp_line (start 1.8 -1.3) (end 1.8 1.3) (layer "F.CrtYd") (width 0.05) (tstamp 7844fa1c-c2e9-46d4-aee9-55128915096f))
|
||||
(fp_line (start -1.8 1.3) (end -1.8 -1.3) (layer "F.CrtYd") (width 0.05) (tstamp 9ae7e107-47c3-4f43-acc6-d14899796c06))
|
||||
(fp_line (start 1.5 -1) (end -1.5 -1) (layer "F.Fab") (width 0.12) (tstamp 02103ae5-54fb-4b80-a4c2-6096261b830e))
|
||||
(fp_line (start 1.5 1) (end -1.5 1) (layer "F.Fab") (width 0.12) (tstamp 3ada789a-8253-4c52-ac20-d30b9efe4f49))
|
||||
(fp_line (start 1.5 -1) (end 1.5 1) (layer "F.Fab") (width 0.12) (tstamp 8d418f4a-1f96-40d9-af23-daa03b7feb31))
|
||||
(fp_line (start -1.5 -1) (end -1.5 1) (layer "F.Fab") (width 0.12) (tstamp f149694e-4336-45f7-8a0b-aed91118ad18))
|
||||
(pad "1" smd roundrect (at -1.25 -0.75) (size 0.6 0.3) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp 7983b95c-14e4-4dec-ab4e-09c81071d9de))
|
||||
(pad "2" smd roundrect (at -1.25 -0.25) (size 0.6 0.3) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp 3997254a-8057-4464-ba07-e37f0720cbd8))
|
||||
(pad "3" smd roundrect (at -1.25 0.25) (size 0.6 0.3) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp a9ff0621-eacb-4187-ba89-29f236eec881))
|
||||
(pad "4" smd roundrect (at -1.25 0.75) (size 0.6 0.3) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp 8eacb9d3-c41d-4b39-abd1-0bc8f2e97411))
|
||||
(pad "5" smd roundrect (at 1.25 0.75) (size 0.6 0.3) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp d3db736b-0e33-4126-b950-5488923df40e))
|
||||
(pad "6" smd roundrect (at 1.25 0.25) (size 0.6 0.3) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp f7475c2a-e91e-435c-bec2-3307ef3e1f94))
|
||||
(pad "7" smd roundrect (at 1.25 -0.25) (size 0.6 0.3) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp a16dbf15-8f5b-4766-b048-90ba89efcc02))
|
||||
(pad "8" smd roundrect (at 1.25 -0.75) (size 0.6 0.3) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp cf45f134-35c0-4b31-91e7-048e45f34bf8))
|
||||
(pad "9" smd roundrect (at 0 0 180) (size 0.3 1.7) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.25) (tstamp d1f81642-eb3a-4277-b357-9cbb5a3aa5ac))
|
||||
(model "${KIPRJMOD}/../mta1-library/mta1.pretty/3d_models/USON_2X3.step"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz -90 0 0))
|
||||
)
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue