Simple CPU in Xilinx Spartan 3E FPGA based Digilent Basys2 board

This simple CPU is running on Digilent Basys2 with basic instructions. It is Von Neumann architecture. Each instruction is 32 bit. ALU(Arithmetic Logic Unit) is capable of 32 bit if operands are loaded from memory. Otherwise direct operations only support 14 bit. GitHub (https://github.com/hasanunlu/simple_cpu) has all necessary files (Design files, binary download, memory dump and example bubble sort assembly file)

Screen Shot 2018-08-27 at 12.01.39 AM

Instruction Set of Simple CPU:

ADD -> unsigned Add
{opcode, i} = {0, 0}
*A <- (*A) + (*B)
write ( readFromAddress(A) + readAddress(B) ) to address ( A )
*A = value (content of) address A = mem[A] (mem means memory)
*B = value (content of) address B = mem[B]
<- means write (assign)
mem[A] = mem[A] + mem[B]
mem[IW[27:14]] = mem[IW[27:14]] + mem[IW[13:0]]

ADDi -> unsigned Add immediate
{opcode, i} = {0, 1}
*A <- (*A) + B
B = read section B of the Instruction
mem[A] = mem[A] + B
mem[IW[27:14]] = mem[IW[27:14]] + IW[13:0]

MUL -> unsigned Multiply
{opcode, i} = {7, 0}
*A <- (*A) * (*B)

MULi -> unsigned Multiply
{opcode, i} = {7, 1}
*A <- (*A) * B

NAND -> bitwise NAND
{opcode, i} = {1, 0}
*A <- ~((*A) & (*B))
{opcode, i} = {0, 1}

NANDi -> bitwise NAND immediate
{opcode, i} = {1, 1}
*A <- ~((*A) & B)

SRL -> Shift Right if the shift amount (*B) is less than 32, otherwise Shift Left
{opcode, i} = {2, 0}
*A (*B)) : ((*A) << ((*B) – 32))

SRLi -> Shift Right if the shift amount (B) is less than 32, otherwise Shift Left
{opcode, i} = {2, 0}
*A B) : ((*A) << (B – 32))

LT -> if *A is Less Than *B then *A is set to 1, otherwise to 0.
{opcode, i} = {3, 0}
*A <- ((*A) < (*B))

LTi -> if *A is Less Than B then *A is set to 1, otherwise to 0.
{opcode, i} = {3, 1}
*A <- ((*A) < B)

CP -> Copy *B to *A
{opcode, i} = {4, 0}
*A <- *B

CPi -> Copy B to *A
{opcode, i} = {4, 1}
*A <- B

CPI -> (regular) Copy Indirect: Copy **B to *A
(go to address B and fetch the number then treat it as an address and go to that address and get that data and write to address A)
{opcode, i} = {5, 0}
*A <- *(*B)
write ( readFromAddress(readFromAddress(B)) ) to address ( A )

CPIi -> (immediate) Copy Indirect: Copy *B to **A
(go to address B and fetch the number (*B) then go to address A and fetch the number there and treat it as an address and write there *B)
{opcode, i} = {5, 1}
*(*A) <- *B
write ( readFromAddress(B) ) to address ( readFromAddress(A) )

BZJ -> Branch on Zero
(Branch to *A if *B is Zero, otherwise increment Program Counter (PC))
{opcode, i} = {6, 0}
PC <- (*B == 0) ? (*A) : (PC+1)
if(*B == 0) goTo(*A), else goTo(nextInstruction)

BZJi -> Jump (unconditional branch)
{opcode, i} = {6, 1}
PC <- (*A) + B

Example bubble sort assembly code: bubble_sort.asm

Full Speed Bit-Bang I2C demo for Risc-V architecture HiFive-1 board

HiFive-1 is first Arduino compatible Risc-V board. Unfortunately HiFive-1 only has PMW, UART and SPI hardware. Over the weekend, I implemented bit-bang I2C clocking up to 400KHz for my HiFive-1 board. Demo uses MPU6050 sensor read all axises and prints g in axis Z.

Screenshot from 2018-08-26 22-39-01

The code is here: https://github.com/hasanunlu/i2c_demo_for_HiFive1

Next step, I will migrate my balancing robot codes to here. Because risc-V is clocking around ~300MHz, so the control loop would be running in higher frequencies.

IMG_0209

Speed of Light Measurement using Texas Instrument TDC7201 (Basic LIDAR concept)

In this experiment, we measure light delay in 15 meters fiber cable using TDC7201 Time to digital converter. I used common parts you can find any where easily. All fiber cables in here are Toslink optical cable and very cheap. My measurement is 99.2[ns] in 15 meters cable. If it is in vacuum environment, light would travel same distance in 50[ns]. Normally refraction index is 1.3 for fiber cables but this cable might be different I used 10 meter fiber cable in same brand, at that time my measurement was 65.8[ns]. So same fiber cable result is correlated.

Part list:

  • Arduino Due or similar micro controller which has SPI and 3.3V logic level
  • TI TDC7201 evaluation board [http://www.ti.com/lit/ds/snas686/snas686.pdf]
  • Red light laser
  • 2 photo diode
  • 7404 for basic laser diode driving (or any transistor based driver would be fine)
  • OLED or other display [Optional] Because, output is also printed to serial terminal
  • 15 meters optical cable
  • Optical Splitter

Screen Shot 2018-01-14 at 12.14.18 PM

Arduino Due codes: https://github.com/hasanunlu/tdc_7201

Intermediate Axis Theorem

One of the interesting physics phenomena is intermediate axis theorem, if the rigid object has increasing moment of inertia for each orthogonal axis and you spin it axis of intermediate moment of inertia it oscillates.

Here is the video:

The analysis of system using rigid body equations:

Screen Shot 2017-10-24 at 12.51.55 AM

In that case M_1, M_2 and M_3 are zero. $latex I_1 < I_2 0, w_1\approx 0 $ and w_3\approx 0 , in order to solve higher order differential equation MATLAB can be used. Here is func.m file:

function dydt = func(t,y)
I1=1;
I2=2;
I3=3;
dydt = zeros(3,1);
dydt(1) = (I2-I3)*y(2)*y(3)/I1;
dydt(2) = (I3-I1)*y(1)*y(3)/I2;
dydt(3) = (I1-I2)*y(1)*y(2)/I3;

from command line or other .m file run the following lines.

clear all;
[t, y]=ode45(@func,[0:0.1:100],[.01 4 .01]);
plot(t,y(:,1),t,y(:,2),t,y(:, 3))

Numerical solution of differential equations shows w_2 is oscillating between -4 and 4. While changing rotation, very short amount of time w_1 and w_3 are non zero.
data1 -> w_1
data2 -> w_2
data3 -> w_3

intermediate_axis