Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example for interaction with the flash device via verilog #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions flashSPI/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
PROJ = controller
DEVICE = 8k
FILES = controller.v

.PHONY: all clean

all:
yosys -p "synth_ice40 -top main -json $(PROJ).json" $(FILES)
nextpnr-ice40 -r --hx8k --json $(PROJ).json --package cb132 --asc $(PROJ).asc --opt-timing --pcf iceFUN.pcf
icepack $(PROJ).asc $(PROJ).bin
iceFUNprog $(PROJ).bin

clean:
rm *.asc *.bin *blif *.out *.json *.history *.vcd .sconsign.dblite
13 changes: 13 additions & 0 deletions flashSPI/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Flash Read ID Operation

This project directory contains an implimentation of the `Resume from Deep Power-Down and Read Device ID (ABh) ` operation initiated by the FPGA device on the iceFUN, to the [flash device](https://www.digikey.com/htmldatasheets/production/1568138/0/0/1/at25sf081-shd-t.html) on the iceFUN.

# Use

It is possible to install the necessary pre-requisites for compilation and testing from two sources:

- [robot electronics webpage](https://www.robot-electronics.co.uk/icefun.html)

- [apio](https://github.com/FPGAwars/apio)

Once binary is flashed to the iceFUN, the leds will desplay the deviceID
3 changes: 3 additions & 0 deletions flashSPI/apio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[env]
board = icefun
top-module = main
61 changes: 61 additions & 0 deletions flashSPI/controller.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
*
* Copyright(C) 2024 Kai Harris <[email protected]>
*
* 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.
*
*/

`include "sub_clock_module.v"
`include "flash_module.v"
`include "leds.v"

module main (
input clk,
input miso,
output cs,
output sck,
output mosi,
output [7:0] led,
output [3:0] col
);

/*system wiring*/
wire [7:0] flash_response;
wire sub_clock, SI_out_clock;

/*clock module management*/
sub_clock_module sub_clock_module (
.top_clk(clk),
.sub_clock(sub_clock),
.SI_out_clock(SI_out_clock)
);

/*flash module management*/
flash_module flash_module (
.top_clk(sub_clock),
.sub_clk(SI_out_clock),
.miso(miso),
.cs(cs),
.sck(sck),
.mosi(mosi),
.flash_response(flash_response)
);

/*led module management*/
led_module led_module (
.led_set(flash_response),
.led(led),
.col(col)
);

endmodule
107 changes: 107 additions & 0 deletions flashSPI/flash_module.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
*
* Copyright(C) 2024 Kai Harris <[email protected]>
*
* 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.
*
*/

module flash_module(
input top_clk,
input sub_clk,
input miso,
output cs,
output sck,
output mosi,
output [7:0] flash_response
);
/*operation state*/
parameter await_delay = 0;
parameter perform_op = 1;
reg clock_state;

/*long gap between operations*/
parameter OPERATION_DELAY = 14'b11111111111111;
reg [13:0] delay_counter;

/*opcode*/
parameter [31:0] OPCODE = {4'b1010, 4'b1011, 8'b0, 8'b0, 8'b0};

/*counters and flags*/
integer operation_counter;
integer SI_pulse, SO_pulse;
reg clock_start_flag;

/*module wiring*/
reg CS_register, MOSI_register, SCK_register;
reg [7:0] FLASH_RESPONSE;
assign cs = CS_register;
assign sck = SCK_register;
assign mosi = MOSI_register;
assign flash_response = FLASH_RESPONSE;

/*initialisation*/
initial begin
clock_state <= await_delay;
delay_counter <= 0;
operation_counter <= 0;
SI_pulse <= 0;
clock_start_flag <= 0;
CS_register <= 1;
MOSI_register <= OPCODE[31];
FLASH_RESPONSE <= 8'b11111111;
end

/*CS, SI and SO control*/
always @ (posedge sub_clk) begin
case (clock_state)
await_delay : begin
delay_counter <= delay_counter + 1;
if (delay_counter == OPERATION_DELAY - 1) begin
CS_register <= 0;
clock_state <= perform_op;
end
end
perform_op : begin
if (delay_counter == OPERATION_DELAY) begin
clock_start_flag <= 1;
end begin
operation_counter <= operation_counter + 1;
if (operation_counter <= 31) begin
SI_pulse <= SI_pulse + 1;
MOSI_register <= OPCODE[31-SI_pulse];
end
if (operation_counter >= 31 && operation_counter < 39) begin
SO_pulse <= SO_pulse + 1;
FLASH_RESPONSE[7-SO_pulse] <= miso;
end
if (operation_counter == 39) begin
clock_state <= await_delay;
delay_counter <= 0;
operation_counter <= 0;
SI_pulse <= 0;
clock_start_flag <= 0;
MOSI_register <= OPCODE[31];
CS_register <= 1;
end
end
end
endcase
end

/*SCK wiring control*/
always @ (*) begin
if (clock_start_flag) SCK_register <= top_clk;
else SCK_register <= 0;
end

endmodule
21 changes: 21 additions & 0 deletions flashSPI/iceFUN.pcf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Pinout defined by hardware vendor here: https://www.robot-electronics.co.uk/files/iceFUNdoc.pdf

set_io --warn-no-port led[0] C10
set_io --warn-no-port led[1] A10
set_io --warn-no-port led[2] D7
set_io --warn-no-port led[3] D6
set_io --warn-no-port led[4] A7
set_io --warn-no-port led[5] C7
set_io --warn-no-port led[6] A4
set_io --warn-no-port led[7] C4
set_io --warn-no-port col[0] A12
set_io --warn-no-port col[1] D10
set_io --warn-no-port col[2] A6
set_io --warn-no-port col[3] C5

set_io --warn-no-port clk P7

set_io --warn-no-port cs P13
set_io --warn-no-port sck P12
set_io --warn-no-port miso P11
set_io --warn-no-port mosi M11
40 changes: 40 additions & 0 deletions flashSPI/leds.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
*
* Copyright(C) 2024 Kai Harris <[email protected]>
*
* 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.
*
*/

module led_module(
input [7:0] led_set,
output [7:0] led,
output [3:0] col
);
/*led module wiring*/
reg [7:0] led_register;
reg [3:0] col_register;
assign led = led_register;
assign col = col_register;

/*module initialisation*/
initial begin
led_register <= 8'b11111111;
col_register <= 4'b1110;
end

/*set leds*/
always @(*) begin
led_register <= led_set;
end

endmodule
49 changes: 49 additions & 0 deletions flashSPI/output_tb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
*
* Copyright(C) 2024 Kai Harris <[email protected]>
*
* 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.
*
*/

`timescale 1 ns / 1 ps // Time scale directive, 1 ns time unit, 1 ps time precision

module output_tb();
wire cs, sck, mosi;
reg clk = 0;

localparam CLK_PERIOD = 83.33; // 12 MHz clock -> 1/12_000_000 second period -> 83.33 nanosecons
localparam HALF_CLK_PERIOD = 41.67;
localparam DURATION = 1000000;

main uut (
.clk(clk),
.cs(cs),
.sck(sck),
.mosi(mosi)
);

// VCD dump for waveform analysis
initial begin
$dumpfile("output_tb.vcd"); // Create VCD file for simulation waveform output
$dumpvars(0, output_tb); // Dump variables from top module (output_tb)
#(DURATION); // Run simulation for specified duration
$finish; // End the simulation
end

// Clock generation block
always begin
#(HALF_CLK_PERIOD) // Half-period delay
clk = ~clk; // Toggle clock signal every half period
end

endmodule
74 changes: 74 additions & 0 deletions flashSPI/sub_clock_module.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
*
* Copyright(C) 2024 Kai Harris <[email protected]>
*
* 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.
*
*/

module sub_clock_module(
input top_clk,
output sub_clock,
output SI_out_clock
);

/*output clock hyperparameters*/
parameter LOW = 0;
parameter HIGH = 1;
parameter HIGH_COUNT = 2;
parameter LOW_COUNT = 20;
parameter LOW_COUNT_RISING = 15;

/*counters*/
integer high_counter;
integer low_counter;

/*module wiring*/
reg clock_state_active, SI_out_reg;
assign sub_clock = clock_state_active;
assign SI_out_clock = SI_out_reg;

/*module initialisation*/
initial begin
clock_state_active <= LOW;
SI_out_reg <= 1;
high_counter <= 0;
low_counter <= 0;
end

/*output clock signal management*/
always @(posedge top_clk) begin
case (clock_state_active)
LOW : begin
if (low_counter < LOW_COUNT) low_counter <= low_counter + 1;
if (low_counter == LOW_COUNT) begin
clock_state_active <= HIGH;
low_counter <= 0;
end
if (low_counter == LOW_COUNT_RISING) begin
SI_out_reg <= 1;
end
if (low_counter != LOW_COUNT_RISING) begin
SI_out_reg <= 0;
end
end
HIGH : begin
if (high_counter == HIGH_COUNT) begin
clock_state_active <= LOW;
high_counter <= 0;
end
else high_counter <= high_counter + 1;
end
endcase
end

endmodule