Skip to content

Commit

Permalink
Added the spin demo (demo3)
Browse files Browse the repository at this point in the history
  • Loading branch information
wd5gnr committed Aug 27, 2018
1 parent 8abd5d3 commit 5bb6b0c
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 0 deletions.
80 changes: 80 additions & 0 deletions demos/ice40/demo3/config_verifla.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* This is the Verifla configuration file
You should have this in your work directory for each project
You should have the verifla library under your work directory
either as a symlink or a copy
The library code will look for ../verifla_config.v (this file)
*/

// ********* TIMING and COMMUNICATONS
parameter CLOCK_FREQUENCY = 12_000_000;
// If CLOCK_FREQUENCY < 50 MHz then BAUDRATE must be < 115200 bps (for example 9600).
parameter BAUDRATE = 9600;
// The Baud Counter Size must have enough bits or more to hold this constant
parameter T2_div_T1_div_2 = CLOCK_FREQUENCY / (BAUDRATE * 16 * 2);
// Assert: BAUD_COUNTER_SIZE >= log2(T2_div_T1_div_2) bits
parameter BAUD_COUNTER_SIZE = 15;

// ********* Data Setup
// Number of data inputs (must be a multile of 8)
parameter LA_DATA_INPUT_WORDLEN_BITS=16;

// ******** Trigger
// Your data & LA_TRIGGER_MASK must equal LA_TRIGGER_VALUE to start a complete capture
parameter LA_TRIGGER_VALUE=16'h0002, LA_TRIGGER_MASK=16'h0003;

// To help store more data, the LA counts how many samples are identical
// The next parameter is the size of the repeat count. Must be a multiple of 8 bits
// If the count overflows you just get another sample that starts counting again.
parameter LA_IDENTICAL_SAMPLES_BITS=16;

// ******** Memory Setup
// Pick how many address bits you'll use and the first and last address
// The first address will almost always be 0 and the last will almost always
// be 2^bits-1. For example, 8,0,255 or 10,0,1023
parameter LA_MEM_ADDRESS_BITS=10;
parameter LA_MEM_FIRST_ADDR=0,
LA_MEM_LAST_ADDR=1023;
// The memory is divided into two regions. The first region is a circular buffer
// that stores all data before the trigger. Then the trigger occurs and is stored
// at a fixed address. All the data after the trigger occurs after that. The last word
// of memory is reserved for a tail pointer to the circular buffer
// For example, if the memory size is 1K
// You might set the next parameter to 500. This would store up to 500
// lines of data before the trigger (because of the repeat count, this could be more than
// 500 samples). It could store less, because the buffer could be not full when
// the trigger occurs. Then the trigger word will be at address 500 and the remaining
// samples will follow. The last word of the memory will indicate where the last write
// in the buffer was (thus, the next address is the oldest data in the buffer).
// TLDR: What address do I use to start storing the trigger and subsequent data
parameter LA_TRIGGER_MATCH_MEM_ADDR=513;
// The LA will continue to capture after the trigger until a certain number of samples
// arrive or memory is full. Because of the repeat count, a low number here could
// just cause the sample to stop on the trigger. For example, suppose the input
// will not change for 50 cycles after the trigger and you set this to 20 samples.
// You would just get a repeat count of 20 on the trigger word.
// If you like, set this value to something very large and you'll better use memory
// Be sure the number of bits is enough to hold the count
parameter LA_MAX_SAMPLES_AFTER_TRIGGER_BITS=24;
parameter LA_MAX_SAMPLES_AFTER_TRIGGER=100000;
// Because the circular buffer and the post trigger buffer may not be full
// You may want to let the LA write a known value to the buffer before starting
// The tools are good about hiding these data "holes" from you, though

// Set this to 1 if you want to fill the buffer with a marker value
parameter LA_MEM_CLEAN_BEFORE_RUN=1;
parameter LA_MEM_EMPTY_SLOT=8'hEE;

// ********** Below this you shouldn't have to change anything

parameter LA_MEM_WORDLEN_BITS=(LA_DATA_INPUT_WORDLEN_BITS+LA_IDENTICAL_SAMPLES_BITS);
parameter LA_MEM_WORDLEN_OCTETS=((LA_MEM_WORDLEN_BITS+7)/8);
parameter LA_BT_QUEUE_TAIL_ADDRESS=LA_MEM_LAST_ADDR;
// constraint: (LA_MEM_FIRST_ADDR + 4) <= LA_TRIGGER_MATCH_MEM_ADDR <= (LA_MEM_LAST_ADDR - 4)
//parameter LA_TRIGGER_MATCH_MEM_ADDR=((1 << LA_MEM_ADDRESS_BITS) >> 3),

parameter LA_MEM_LAST_ADDR_BEFORE_TRIGGER=(LA_TRIGGER_MATCH_MEM_ADDR-1);

// Identical samples
parameter LA_MAX_IDENTICAL_SAMPLES=((1 << LA_IDENTICAL_SAMPLES_BITS) - 2);


17 changes: 17 additions & 0 deletions demos/ice40/demo3/go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
LADIR="../../../verilog/verifla"
if [ -z "$1" ]
then
FN="example_icestick"
else
FN="$1"
fi
if ! yosys -p "read_verilog $YOSYS_OPTS -noautowire \"$FN.v\" ; hierarchy -libdir . ; hierarchy -libdir $LADIR ; synth_ice40 -blif $FN.blif"
then exit
fi
if ! arachne-pnr $ARACHNE_OPTS -d 1k -p $FN.pcf -o $FN.txt $FN.blif
then exit
fi
icepack $FN.txt $FN.bin
iceprog $FN.bin

78 changes: 78 additions & 0 deletions demos/ice40/demo3/spin.pcf
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# ##############################################################################

# iCEstick PCF

# ##############################################################################

# This is the version that you don't have to uncomment
# things you don't use. Requires a recent version of arachne

# Clock
set_io --warn-no-port clk 21 # 12 MHz clock

# LEDs
set_io --warn-no-port LED1 99 # red
set_io --warn-no-port LED2 98 # red
set_io --warn-no-port LED3 97 # red
set_io --warn-no-port LED4 96 # red
set_io --warn-no-port LED5 95 # green

# IRDA interface
set_io --warn-no-port IRRXD 106
set_io --warn-no-port IRTXD 105
set_io --warn-no-port IRSD 107

# SPI (to configuration EEPROM)
set_io --warn-no-port SPI_SCK 70
set_io --warn-no-port SPI_SI 68
set_io --warn-no-port SPI_SO 67
set_io --warn-no-port SPI_SS 71

# J1
# set_io --warn-no-port J1_1 3.3V
# set_io --warn-no-port J1_2 GND
set_io --warn-no-port J1_3 112 # PIO0_02
set_io --warn-no-port J1_4 113 # PIO0_03
set_io --warn-no-port J1_5 114 # PIO0_04
set_io --warn-no-port J1_6 115 # PIO0_05
set_io --warn-no-port J1_7 116 # PIO0_06 PMOD pin 7
set_io --warn-no-port J1_8 117 # PIO0_07 PMOD pin 8
set_io --warn-no-port J1_9 118 # PIO0_08 PMOD pin 9
set_io --warn-no-port J1_10 119 # PIO0_09 PMOD pin 10

# J3
# set_io --warn-no-port J3_1 3.3V
# set_io --warn-no-port J3_2 GND
set_io --warn-no-port J3_3 62 # PIO2_17
set_io --warn-no-port J3_4 61 # PIO2_16
set_io --warn-no-port J3_5 60 # PIO2_15
set_io --warn-no-port J3_6 56 # PIO2_14
set_io --warn-no-port J3_7 48 # PIO2_13
set_io --warn-no-port J3_8 47 # PIO2_12
set_io --warn-no-port J3_9 45 # PIO2_11
set_io --warn-no-port J3_10 44 # PIO2_10

# PMOD
# Note: pin 5 and 11 are ground, pins 6 and 12 are Vcc
set_io --warn-no-port PMOD1 78 # PIO1_02
set_io --warn-no-port PMOD2 79 # PIO1_03
set_io --warn-no-port PMOD3 80 # PIO1_04
set_io --warn-no-port PMOD4 81 # PIO1_05
set_io --warn-no-port PMOD7 87 # PIO1_06
set_io --warn-no-port PMOD8 88 # PIO1_07
set_io --warn-no-port PMOD9 90 # PIO1_08
set_io --warn-no-port PMOD10 91 # PIO1_09


# FTDI Port B UART
set_io --warn-no-port DCDn 1
set_io --warn-no-port DSRn 2
set_io --warn-no-port DTRn 3
set_io --warn-no-port CTSn 4
set_io --warn-no-port RTSn 7
set_io --warn-no-port RS232_Tx 8
set_io --warn-no-port RS232_Rx 9

# Config pins
set_io --warn-no-port CDONE 65
set_io --warn-no-port CRESET_B 66
107 changes: 107 additions & 0 deletions demos/ice40/demo3/spin.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
`default_nettype none
module top(input clk, output LED1, output LED2, output LED3,
output LED4, output LED5, output RS232_Tx, input RS232_Rx);


reg [15:0] count=0;
reg [7:0] ctimer=0;

reg [3:0] laresetct=0;
wire lareset;


assign lareset = (laresetct==4'b0000 || laresetct==4'b1111);




// logic analyzer
// Since the state machine can only change when count==0, using the clock qualifer
// lets us skip so many repeating values
top_of_verifla verifla(.clk(clk),.cqual(1'b1),.rst_l(lareset), .sys_run(1'b0),
.data_in({ctimer,6'b0,state}),
.uart_XMIT_dataH(RS232_Tx),
.uart_REC_dataH(RS232_Rx));


// generate POR reset for logic analyzer
always @(posedge clk) if (laresetct!=4'b1111) laresetct<=laresetct+4'b0001;



/*
Simple state machine
CW - n=n+1, led-on ctimer=250, >CWAIT
CWAIT - wait for timer, if n==3 >CCW else >CW
CCW - n=n-1, led-on ctimer=250, CCWAIT
CCWAIT - wait for timer, if n==0 >CW else CCW
*/

// dense encoding
localparam CW = 2'b00;
localparam CWAIT = 2'b01;
localparam CCW = 2'b10;
localparam CCWAIT = 2'b11;


reg [1:0] state=CW;
reg [3:0] leds=1;
reg blink=0;




assign LED1=leds[0];
assign LED2=leds[1];
assign LED3=leds[2];
assign LED4=leds[3];
assign LED5=blink;





always @(posedge clk)
begin
count<=count+1;
if (ctimer!=0 && count==0) ctimer<=ctimer-1;
case (state)
CW:
begin
leds={leds[2:0],1'b0};
ctimer<=250;
blink<=~blink;
state<=CWAIT;
end
CWAIT:
begin
if (ctimer==0)
begin
state<=leds[3]?CCW:CW;
end
end
CCW:
begin
leds={1'b0,leds[3:1]};
blink<=~blink;
ctimer<=250;
state=CCWAIT;
end
CCWAIT:
begin
if (ctimer==0)
begin
state<=leds[0]?CW:CCW;
end
end
default:
begin
state<=CW; // never gets here we hope
end
endcase // case (state)
end


endmodule // top

0 comments on commit 5bb6b0c

Please sign in to comment.