├── .gitignore
├── README.md
├── doc
├── EMMC_JESD84-A441.pdf
├── Part1_Physical_Layer_Simplified_Specification_Ver6.00.pdf
├── PartE1_SDIO_Simplified_Specification_Ver3.00.pdf
└── micro_sd_pinout.png
├── fpga
├── sdio_project
│ ├── code
│ │ ├── logic_analyzer
│ │ │ ├── logic_alanyser_fifo8_async.qip
│ │ │ ├── logic_alanyser_fifo8_async.v
│ │ │ ├── logic_analyzer_controller_200mhz.sv
│ │ │ ├── logic_analyzer_controller_200mhz_serial48.sv
│ │ │ ├── logic_analyzer_controller_bytecopy.sv
│ │ │ ├── logic_analyzer_controller_quadspi.sv
│ │ │ ├── logic_analyzer_fifo_async.qip
│ │ │ └── logic_analyzer_fifo_async.v
│ │ ├── pll
│ │ │ ├── pll200mhz.ppf
│ │ │ ├── pll200mhz.qip
│ │ │ └── pll200mhz.v
│ │ ├── root_logic_analyzer.sv
│ │ ├── sdio_slave
│ │ │ ├── cis.mem
│ │ │ ├── sd_crc16.sv
│ │ │ ├── sd_crc7.sv
│ │ │ ├── sd_read_stream.sv
│ │ │ ├── sd_read_stream_dat.sv
│ │ │ ├── sd_response_stream.sv
│ │ │ ├── sd_response_stream_dat.sv
│ │ │ ├── sd_typedef.sv
│ │ │ ├── sdio_commands_processor.sv
│ │ │ └── sdio_slave.sv
│ │ ├── signal_timer.sv
│ │ └── uart
│ │ │ ├── uart_rx.sv
│ │ │ ├── uart_rx_controller.sv
│ │ │ ├── uart_rx_fifo.qip
│ │ │ ├── uart_rx_fifo.v
│ │ │ └── uart_tx.sv
│ ├── sdio_project.qpf
│ ├── sdio_project.qsf
│ ├── sdio_project.sdc
│ └── write_to_flash.cdf
└── verilator_tests
│ ├── sd_crc16
│ ├── Makefile_obj
│ ├── crc16.h
│ ├── makefile
│ ├── sd_crc16.cflags
│ ├── sd_crc16.config
│ ├── sd_crc16.creator
│ ├── sd_crc16.cxxflags
│ ├── sd_crc16.files
│ ├── sd_crc16.includes
│ ├── sim_main.cpp
│ ├── tests.cpp
│ └── tests.h
│ ├── sd_read_stream
│ ├── Makefile_obj
│ ├── makefile
│ ├── sd_read_stream.cflags
│ ├── sd_read_stream.config
│ ├── sd_read_stream.creator
│ ├── sd_read_stream.cxxflags
│ ├── sd_read_stream.files
│ ├── sd_read_stream.includes
│ ├── sim_main.cpp
│ ├── tests.cpp
│ └── tests.h
│ ├── sd_read_stream_dat
│ ├── Makefile_obj
│ ├── makefile
│ ├── sd_read_stream_dat.cflags
│ ├── sd_read_stream_dat.config
│ ├── sd_read_stream_dat.creator
│ ├── sd_read_stream_dat.cxxflags
│ ├── sd_read_stream_dat.files
│ ├── sd_read_stream_dat.includes
│ ├── sim_main.cpp
│ ├── tests.cpp
│ └── tests.h
│ ├── sd_response_stream
│ ├── Makefile_obj
│ ├── crc7.h
│ ├── makefile
│ ├── sd_response_stream.cflags
│ ├── sd_response_stream.config
│ ├── sd_response_stream.creator
│ ├── sd_response_stream.cxxflags
│ ├── sd_response_stream.files
│ ├── sd_response_stream.includes
│ ├── sim_main.cpp
│ ├── tests.cpp
│ └── tests.h
│ └── sd_response_stream_dat
│ ├── Makefile_obj
│ ├── makefile
│ ├── sd_response_stream_dat.cflags
│ ├── sd_response_stream_dat.config
│ ├── sd_response_stream_dat.creator
│ ├── sd_response_stream_dat.cxxflags
│ ├── sd_response_stream_dat.files
│ ├── sd_response_stream_dat.includes
│ ├── sim_main.cpp
│ ├── tests.cpp
│ └── tests.h
├── img
└── overview.jpg
├── info.txt
└── linux
├── balmer_sdio_uart
├── Config.in
├── Makefile
├── README.adoc
├── balmer_sdio_uart.c
├── external.desc
└── external.mk
└── sdio_test
├── Makefile
├── http_server.sh
├── sdio_read.c
├── sdio_write.c
└── time_utils.h
/.gitignore:
--------------------------------------------------------------------------------
1 | *.vcd
2 | *.vvp
3 |
4 | *.sv.bak
5 | *.bak
6 | *.kicad_pcb-bak
7 |
8 | *.creator.user
9 | *.pro.user
10 | *\.user\.4\.9-pre1
11 | */__pycache__
12 | */.qsys_edit/*
13 |
14 | py_code/vcd
15 | py_code/sample
16 |
17 | fpga/verilator_tests/*/obj_dir
18 | fpga/verilator_tests/*/logs
19 |
20 | fpga/sdio_project/db/
21 | fpga/sdio_project/incremental_db/
22 | fpga/sdio_project/output_files/
23 | fpga/sdio_project/simulation/
24 |
25 | linux/sdio_test/read
26 | linux/sdio_test/write
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Общение между FPGA и Allwinner V3S на достаточно быстрой скорости.
2 |
3 | 
4 |
5 | Этот проект предназначен для того, чтобы общаться между Linux и FPGA.
6 | Наша задача - использовать интерфейс для SD карты для передачи данных.
7 | Цель - работать на частоте 50 МГц по четырем проводам.
8 | Это позволит передавать 25 мегабайт в секунду данных в пике.
9 |
10 | В текущий момент работает на частоте 25 МГц.
11 | При передаче по 4096 байт получается скорость 4.5-4.8 МБ/сек как на чтение, так и на запись.
12 |
13 | MIT лицензия кода для FPGA (чтобы его мог использовать кто угодно и как угодно).
14 | Драйвера для Linux под GPL лицензией (ибо такая была в драйвере, с которого начал его переделывать).
15 |
--------------------------------------------------------------------------------
/doc/EMMC_JESD84-A441.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balmerdx/sdio_linux_fpga/e77e89ad648ecdbf16aefb1ca826b12053787748/doc/EMMC_JESD84-A441.pdf
--------------------------------------------------------------------------------
/doc/Part1_Physical_Layer_Simplified_Specification_Ver6.00.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balmerdx/sdio_linux_fpga/e77e89ad648ecdbf16aefb1ca826b12053787748/doc/Part1_Physical_Layer_Simplified_Specification_Ver6.00.pdf
--------------------------------------------------------------------------------
/doc/PartE1_SDIO_Simplified_Specification_Ver3.00.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balmerdx/sdio_linux_fpga/e77e89ad648ecdbf16aefb1ca826b12053787748/doc/PartE1_SDIO_Simplified_Specification_Ver3.00.pdf
--------------------------------------------------------------------------------
/doc/micro_sd_pinout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balmerdx/sdio_linux_fpga/e77e89ad648ecdbf16aefb1ca826b12053787748/doc/micro_sd_pinout.png
--------------------------------------------------------------------------------
/fpga/sdio_project/code/logic_analyzer/logic_alanyser_fifo8_async.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name IP_TOOL_NAME "FIFO"
2 | set_global_assignment -name IP_TOOL_VERSION "18.1"
3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "logic_alanyser_fifo8_async.v"]
5 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/logic_analyzer/logic_alanyser_fifo8_async.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %FIFO%
2 | // GENERATION: STANDARD
3 | // VERSION: WM1.0
4 | // MODULE: dcfifo
5 |
6 | // ============================================================
7 | // File Name: logic_alanyser_fifo8_async.v
8 | // Megafunction Name(s):
9 | // dcfifo
10 | //
11 | // Simulation Library Files(s):
12 | // altera_mf
13 | // ============================================================
14 | // ************************************************************
15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 | //
17 | // 18.1.0 Build 625 09/12/2018 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2018 Intel Corporation. All rights reserved.
22 | //Your use of Intel Corporation's design tools, logic functions
23 | //and other software and tools, and its AMPP partner logic
24 | //functions, and any output files from any of the foregoing
25 | //(including device programming or simulation files), and any
26 | //associated documentation or information are expressly subject
27 | //to the terms and conditions of the Intel Program License
28 | //Subscription Agreement, the Intel Quartus Prime License Agreement,
29 | //the Intel FPGA IP License Agreement, or other applicable license
30 | //agreement, including, without limitation, that your use is for
31 | //the sole purpose of programming logic devices manufactured by
32 | //Intel and sold by Intel or its authorized distributors. Please
33 | //refer to the applicable agreement for further details.
34 |
35 |
36 | // synopsys translate_off
37 | `timescale 1 ps / 1 ps
38 | // synopsys translate_on
39 | module logic_alanyser_fifo8_async (
40 | data,
41 | rdclk,
42 | rdreq,
43 | wrclk,
44 | wrreq,
45 | q,
46 | rdempty,
47 | wrfull);
48 |
49 | input [7:0] data;
50 | input rdclk;
51 | input rdreq;
52 | input wrclk;
53 | input wrreq;
54 | output [7:0] q;
55 | output rdempty;
56 | output wrfull;
57 |
58 | wire [7:0] sub_wire0;
59 | wire sub_wire1;
60 | wire sub_wire2;
61 | wire [7:0] q = sub_wire0[7:0];
62 | wire rdempty = sub_wire1;
63 | wire wrfull = sub_wire2;
64 |
65 | dcfifo dcfifo_component (
66 | .data (data),
67 | .rdclk (rdclk),
68 | .rdreq (rdreq),
69 | .wrclk (wrclk),
70 | .wrreq (wrreq),
71 | .q (sub_wire0),
72 | .rdempty (sub_wire1),
73 | .wrfull (sub_wire2),
74 | .aclr (),
75 | .eccstatus (),
76 | .rdfull (),
77 | .rdusedw (),
78 | .wrempty (),
79 | .wrusedw ());
80 | defparam
81 | dcfifo_component.intended_device_family = "Cyclone IV E",
82 | dcfifo_component.lpm_numwords = 8192,
83 | dcfifo_component.lpm_showahead = "OFF",
84 | dcfifo_component.lpm_type = "dcfifo",
85 | dcfifo_component.lpm_width = 8,
86 | dcfifo_component.lpm_widthu = 13,
87 | dcfifo_component.overflow_checking = "ON",
88 | dcfifo_component.rdsync_delaypipe = 4,
89 | dcfifo_component.underflow_checking = "ON",
90 | dcfifo_component.use_eab = "ON",
91 | dcfifo_component.wrsync_delaypipe = 4;
92 |
93 |
94 | endmodule
95 |
96 | // ============================================================
97 | // CNX file retrieval info
98 | // ============================================================
99 | // Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
100 | // Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
101 | // Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
102 | // Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
103 | // Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
104 | // Retrieval info: PRIVATE: Clock NUMERIC "4"
105 | // Retrieval info: PRIVATE: Depth NUMERIC "8192"
106 | // Retrieval info: PRIVATE: Empty NUMERIC "1"
107 | // Retrieval info: PRIVATE: Full NUMERIC "1"
108 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
109 | // Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
110 | // Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1"
111 | // Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
112 | // Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
113 | // Retrieval info: PRIVATE: Optimize NUMERIC "0"
114 | // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
115 | // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
116 | // Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
117 | // Retrieval info: PRIVATE: UsedW NUMERIC "1"
118 | // Retrieval info: PRIVATE: Width NUMERIC "8"
119 | // Retrieval info: PRIVATE: dc_aclr NUMERIC "0"
120 | // Retrieval info: PRIVATE: diff_widths NUMERIC "0"
121 | // Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
122 | // Retrieval info: PRIVATE: output_width NUMERIC "8"
123 | // Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
124 | // Retrieval info: PRIVATE: rsFull NUMERIC "0"
125 | // Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
126 | // Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
127 | // Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
128 | // Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
129 | // Retrieval info: PRIVATE: wsFull NUMERIC "1"
130 | // Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
131 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
132 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
133 | // Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "8192"
134 | // Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF"
135 | // Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
136 | // Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
137 | // Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "13"
138 | // Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
139 | // Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "4"
140 | // Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
141 | // Retrieval info: CONSTANT: USE_EAB STRING "ON"
142 | // Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "4"
143 | // Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
144 | // Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
145 | // Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL "rdclk"
146 | // Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL "rdempty"
147 | // Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
148 | // Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL "wrclk"
149 | // Retrieval info: USED_PORT: wrfull 0 0 0 0 OUTPUT NODEFVAL "wrfull"
150 | // Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
151 | // Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0
152 | // Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
153 | // Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
154 | // Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
155 | // Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
156 | // Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0
157 | // Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
158 | // Retrieval info: CONNECT: wrfull 0 0 0 0 @wrfull 0 0 0 0
159 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_alanyser_fifo8_async.v TRUE
160 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_alanyser_fifo8_async.inc FALSE
161 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_alanyser_fifo8_async.cmp FALSE
162 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_alanyser_fifo8_async.bsf FALSE
163 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_alanyser_fifo8_async_inst.v FALSE
164 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_alanyser_fifo8_async_bb.v FALSE
165 | // Retrieval info: LIB_FILE: altera_mf
166 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/logic_analyzer/logic_analyzer_controller_200mhz.sv:
--------------------------------------------------------------------------------
1 | module logic_analyzer_controller_200mhz(
2 | input bit clock,
3 | //Командный интерфейс
4 | input bit dev_command_started,
5 | input bit dev_command_processing,
6 | input bit[4:0] dev_command,
7 | output bit dev_busy,
8 | input bit dev_command_data_signal,
9 | input byte dev_data,
10 |
11 | //uart out
12 | output bit uart_tx_send_byte,
13 | output byte uart_tx_byte,
14 | input bit uart_tx_active,
15 |
16 | //led
17 | output bit led_full,
18 |
19 | //Данные, которые мы анализируем
20 | input byte logic_data
21 | );
22 |
23 | typedef enum bit [4:0] {
24 | //Очищает FIFO
25 | //Начинает запись заново
26 | //В текущий момент не работает
27 | LA_CLEAR = 5'h0,
28 |
29 | //Читаем все данные из буфера
30 | //Состоит из блоков по 48 бит = 6 байт
31 | LA_READ_ALL = 5'h1
32 | } LA_COMMANDS;
33 |
34 | //State machine для отсылки байтиков
35 | typedef enum bit [2:0] {
36 | LA_SM_IDLE = 3'h0,
37 | LA_SM_START_READ_WORD = 3'h1,
38 | LA_SM_WAIT_READ_WORD_OR_TX_START = 3'h2,
39 | LA_SM_WAIT_READ_WORD_OR_TX_START2 = 3'h3,
40 | LA_SM_WRITE_WORD = 3'h4
41 | } LA_SM;
42 |
43 | typedef bit [47:0] data_type;
44 | typedef bit [11:0] addr_type;
45 | typedef bit [39:0] time_type;
46 |
47 | bit clock200mhz;
48 |
49 | initial dev_busy = 0;
50 |
51 | data_type fifo_in;
52 | data_type fifo_out;
53 | bit fifo_full;
54 | bit fifo_empty;
55 | bit fifo_read_req = 0;
56 | bit fifo_write_req = 0;
57 |
58 | time_type timer = 0;
59 | byte prev_logic_data = 0;
60 | byte logic_data2 = 0;
61 | byte logic_data3 = 0;
62 |
63 | LA_SM la_sm = LA_SM_IDLE;
64 | bit [3:0] current_byte = 0;
65 |
66 | assign led_full = fifo_full;
67 | assign fifo_in = {prev_logic_data, timer};
68 |
69 | pll200mhz pll200mhz0(
70 | .inclk0(clock),
71 | .c0(clock200mhz),
72 | .locked());
73 |
74 | logic_analyzer_fifo_async logic_analyzer_fifo0(
75 | .data(fifo_in),
76 | .rdclk(clock),
77 | .rdreq(fifo_read_req),
78 | .wrclk(clock200mhz),
79 | .wrreq(fifo_write_req),
80 | .q(fifo_out),
81 | .rdempty(fifo_empty),
82 | .wrfull(fifo_full));
83 |
84 | //bit3 67 - cmd когда он переходит с 1 в 0, значит началась команда,
85 | //ещё много-много тактов вперёд надо сэмплировать.
86 | bit[11:0] sample_count = 0;
87 |
88 | bit is_falling_cmd;
89 | assign is_falling_cmd = logic_data3[3]==1'b1 && logic_data2[3]==1'b0;
90 |
91 | always_ff @(posedge clock200mhz)
92 | begin
93 | timer <= timer+1;
94 | logic_data2 <= logic_data;
95 | logic_data3 <= logic_data2;
96 |
97 | if(sample_count>0)
98 | sample_count <= sample_count-1'd1;
99 | if(is_falling_cmd)
100 | sample_count <= 12'h1FF;
101 | if(fifo_write_req)
102 | fifo_write_req <= 0;
103 |
104 | if(is_falling_cmd || (sample_count>0 && logic_data2!=prev_logic_data))
105 | begin
106 | prev_logic_data <= logic_data2;
107 | fifo_write_req <= 1;
108 | end
109 | end
110 |
111 | always_ff @(posedge clock)
112 | begin
113 | if(fifo_read_req)
114 | fifo_read_req <= 0;
115 |
116 | if(uart_tx_send_byte)
117 | uart_tx_send_byte <= 0;
118 |
119 | if(dev_command_started)
120 | begin
121 | case(dev_command)
122 | LA_CLEAR:
123 | begin
124 | end
125 | LA_READ_ALL:
126 | begin
127 | la_sm <= LA_SM_START_READ_WORD;
128 | end
129 | endcase
130 | end
131 |
132 | case(la_sm)
133 | LA_SM_IDLE : ;
134 | LA_SM_START_READ_WORD:
135 | if(fifo_empty)
136 | begin
137 | la_sm <= LA_SM_IDLE;
138 | end
139 | else
140 | begin
141 | fifo_read_req <= 1;
142 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START;
143 | current_byte <= 0;
144 | end
145 |
146 | LA_SM_WAIT_READ_WORD_OR_TX_START:
147 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START2;
148 |
149 | LA_SM_WAIT_READ_WORD_OR_TX_START2:
150 | la_sm <= LA_SM_WRITE_WORD;
151 |
152 | LA_SM_WRITE_WORD:
153 | if(!uart_tx_active)
154 | begin
155 | if(current_byte==6)
156 | begin
157 | current_byte <= 0;
158 | la_sm <= LA_SM_START_READ_WORD;
159 | end
160 | else
161 | begin
162 | uart_tx_byte <= fifo_out[8*current_byte +: 8];
163 | uart_tx_send_byte <= 1;
164 | current_byte <= current_byte+1'd1;
165 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START;
166 | end
167 | end
168 | endcase
169 | end
170 |
171 | endmodule
172 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/logic_analyzer/logic_analyzer_controller_200mhz_serial48.sv:
--------------------------------------------------------------------------------
1 | module logic_analyzer_controller_200mhz_serial48(
2 | input bit clock,
3 | input bit clock200mhz,
4 | //Командный интерфейс
5 | input bit dev_command_started,
6 | input bit dev_command_processing,
7 | input bit[4:0] dev_command,
8 | output bit dev_busy,
9 | input bit dev_command_data_signal,
10 | input byte dev_data,
11 |
12 | //uart out
13 | output bit uart_tx_send_byte,
14 | output byte uart_tx_byte,
15 | input bit uart_tx_active,
16 |
17 | //led
18 | output bit led_full,
19 |
20 | //Данные, которые мы анализируем
21 | //Все посылки по 48 бит
22 | //Начинаются с перехода logic_serial 1->0
23 | input bit logic_clock,
24 | input bit logic_serial
25 | );
26 |
27 | typedef enum bit [4:0] {
28 | //Очищает FIFO
29 | //Начинает запись заново
30 | //В текущий момент не работает
31 | LA_CLEAR = 5'h0,
32 |
33 | //Читаем все данные из буфера
34 | //Состоит из блоков по 48 бит = 6 байт
35 | LA_READ_ALL = 5'h1
36 | } LA_COMMANDS;
37 |
38 | //State machine для отсылки байтиков
39 | typedef enum bit [2:0] {
40 | LA_SM_IDLE = 3'h0,
41 | LA_SM_START_READ_WORD = 3'h1,
42 | LA_SM_WAIT_READ_WORD_OR_TX_START = 3'h2,
43 | LA_SM_WAIT_READ_WORD_OR_TX_START2 = 3'h3,
44 | LA_SM_WRITE_WORD = 3'h4
45 | } LA_SM;
46 |
47 | typedef bit [47:0] data_type;
48 |
49 | initial dev_busy = 0;
50 |
51 | data_type fifo_in;
52 | data_type fifo_out;
53 | bit fifo_full;
54 | bit fifo_empty;
55 | bit fifo_read_req = 0;
56 | bit fifo_write_req = 0;
57 |
58 | bit logic_clock2 = 0;
59 | bit logic_clock3 = 0;
60 | bit logic_serial2 = 0;
61 | bit logic_serial_prev = 0;
62 |
63 | LA_SM la_sm = LA_SM_IDLE;
64 | bit [3:0] current_byte = 0;
65 |
66 | assign led_full = fifo_full;
67 |
68 | logic_analyzer_fifo_async logic_analyzer_fifo0(
69 | .data(fifo_in),
70 | .rdclk(clock),
71 | .rdreq(fifo_read_req),
72 | .wrclk(clock200mhz),
73 | .wrreq(fifo_write_req),
74 | .q(fifo_out),
75 | .rdempty(fifo_empty),
76 | .wrfull(fifo_full));
77 |
78 | //bit3 67 - cmd когда он переходит с 1 в 0, значит началась команда,
79 | //ещё много-много тактов вперёд надо сэмплировать.
80 | bit[5:0] current_bit = 0;
81 | bit start_word_capture = 0;
82 |
83 | bit is_falling_clock;
84 | bit is_rising_clock;
85 | assign is_falling_clock = logic_clock3==1'b1 && logic_clock2==1'b0;
86 | assign is_rising_clock = logic_clock3==1'b0 && logic_clock2==1'b1;
87 |
88 | always_ff @(posedge clock200mhz)
89 | begin
90 | logic_clock2 <= logic_clock;
91 | logic_clock3 <= logic_clock2;
92 | logic_serial2 <= logic_serial;
93 | fifo_write_req <= 0;
94 |
95 | if(is_rising_clock)
96 | begin
97 | //logic_serial2 - это наше текущее значение, вычитанное при falling
98 | logic_serial_prev <= logic_serial2;
99 |
100 | if(logic_serial_prev==1'b1 && logic_serial2==0 && start_word_capture==0)
101 | begin
102 | current_bit <= 46;
103 | fifo_in[47] <= 1'b0;
104 | start_word_capture <= 1'b1;
105 | end
106 |
107 | if(start_word_capture)
108 | begin
109 | fifo_in[current_bit] <= logic_serial2;
110 | if(current_bit>0)
111 | begin
112 | current_bit <= current_bit-1'b1;
113 | end
114 | else
115 | begin
116 | fifo_write_req <= 1'b1;
117 | start_word_capture <= 0;
118 | end
119 | end
120 | end
121 | end
122 |
123 | always_ff @(posedge clock)
124 | begin
125 | if(fifo_read_req)
126 | fifo_read_req <= 0;
127 |
128 | if(uart_tx_send_byte)
129 | uart_tx_send_byte <= 0;
130 |
131 | if(dev_command_started)
132 | begin
133 | case(dev_command)
134 | LA_CLEAR:
135 | begin
136 | end
137 | LA_READ_ALL:
138 | begin
139 | la_sm <= LA_SM_START_READ_WORD;
140 | end
141 | endcase
142 | end
143 |
144 | case(la_sm)
145 | LA_SM_IDLE : ;
146 | LA_SM_START_READ_WORD:
147 | if(fifo_empty)
148 | begin
149 | la_sm <= LA_SM_IDLE;
150 | end
151 | else
152 | begin
153 | fifo_read_req <= 1;
154 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START;
155 | current_byte <= 0;
156 | end
157 |
158 | LA_SM_WAIT_READ_WORD_OR_TX_START:
159 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START2;
160 |
161 | LA_SM_WAIT_READ_WORD_OR_TX_START2:
162 | la_sm <= LA_SM_WRITE_WORD;
163 |
164 | LA_SM_WRITE_WORD:
165 | if(!uart_tx_active)
166 | begin
167 | if(current_byte==6)
168 | begin
169 | current_byte <= 0;
170 | la_sm <= LA_SM_START_READ_WORD;
171 | end
172 | else
173 | begin
174 | uart_tx_byte <= fifo_out[8*current_byte +: 8];
175 | uart_tx_send_byte <= 1;
176 | current_byte <= current_byte+1'd1;
177 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START;
178 | end
179 | end
180 | endcase
181 | end
182 |
183 | endmodule
184 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/logic_analyzer/logic_analyzer_controller_bytecopy.sv:
--------------------------------------------------------------------------------
1 | module logic_analyzer_controller_bytecopy(
2 | input bit clock,
3 | //Командный интерфейс
4 | input bit dev_command_started,
5 | input bit dev_command_processing,
6 | input bit[4:0] dev_command,
7 | output bit dev_busy,
8 | input bit dev_command_data_signal,
9 | input byte dev_data,
10 |
11 | //uart out
12 | output bit uart_tx_send_byte,
13 | output byte uart_tx_byte,
14 | input bit uart_tx_active,
15 |
16 | //led
17 | output bit led_full,
18 |
19 | //Данные, которые мы пишем
20 | input bit data_clock,
21 | input bit data_strobe,
22 | input byte data
23 | );
24 |
25 | typedef enum bit [4:0] {
26 | //Очищает FIFO
27 | //Начинает запись заново
28 | //В текущий момент не работает
29 | LA_CLEAR = 5'h0,
30 |
31 | //Читаем все данные из буфера
32 | //Состоит из блоков по 48 бит = 6 байт
33 | LA_READ_ALL = 5'h1
34 | } LA_COMMANDS;
35 |
36 | //State machine для отсылки байтиков
37 | typedef enum bit [2:0] {
38 | LA_SM_IDLE = 3'h0,
39 | LA_SM_START_READ_WORD = 3'h1,
40 | LA_SM_WAIT_READ_WORD_OR_TX_START = 3'h2,
41 | LA_SM_WAIT_READ_WORD_OR_TX_START2 = 3'h3,
42 | LA_SM_WRITE_WORD = 3'h4
43 | } LA_SM;
44 |
45 | initial dev_busy = 0;
46 |
47 | byte fifo_in;
48 | byte fifo_out;
49 | bit fifo_full;
50 | bit fifo_empty;
51 | bit fifo_read_req = 0;
52 | bit fifo_write_req = 0;
53 |
54 | bit[3:0] logic_data2 = 0;
55 | bit[3:0] logic_data_prev = 0;
56 |
57 | LA_SM la_sm = LA_SM_IDLE;
58 |
59 | assign led_full = fifo_full;
60 |
61 | logic_alanyser_fifo8_async logic_analyzer_fifo0(
62 | .data(fifo_in),
63 | .rdclk(clock),
64 | .rdreq(fifo_read_req),
65 | .wrclk(data_clock),
66 | .wrreq(fifo_write_req),
67 | .q(fifo_out),
68 | .rdempty(fifo_empty),
69 | .wrfull(fifo_full));
70 |
71 |
72 | always_ff @(posedge data_clock)
73 | begin
74 | fifo_in <= data;
75 | fifo_write_req <= data_strobe;
76 | end
77 |
78 | always_ff @(posedge clock)
79 | begin
80 | fifo_read_req <= 0;
81 | uart_tx_send_byte <= 0;
82 |
83 | if(dev_command_started)
84 | begin
85 | case(dev_command)
86 | LA_CLEAR:
87 | begin
88 | end
89 | LA_READ_ALL:
90 | begin
91 | la_sm <= LA_SM_START_READ_WORD;
92 | end
93 | endcase
94 | end
95 |
96 | case(la_sm)
97 | LA_SM_IDLE : ;
98 | LA_SM_START_READ_WORD:
99 | if(fifo_empty)
100 | begin
101 | la_sm <= LA_SM_IDLE;
102 | end
103 | else
104 | begin
105 | fifo_read_req <= 1'd1;
106 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START;
107 | end
108 |
109 | LA_SM_WAIT_READ_WORD_OR_TX_START:
110 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START2;
111 |
112 | LA_SM_WAIT_READ_WORD_OR_TX_START2:
113 | la_sm <= LA_SM_WRITE_WORD;
114 |
115 | LA_SM_WRITE_WORD:
116 | if(!uart_tx_active)
117 | begin
118 | uart_tx_byte <= fifo_out;
119 | uart_tx_send_byte <= 1'd1;
120 | la_sm <= LA_SM_START_READ_WORD;
121 | end
122 | endcase
123 | end
124 |
125 | endmodule
126 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/logic_analyzer/logic_analyzer_controller_quadspi.sv:
--------------------------------------------------------------------------------
1 | module logic_analyzer_controller_quadspi(
2 | input bit clock,
3 | input bit clock200mhz,
4 | //Командный интерфейс
5 | input bit dev_command_started,
6 | input bit dev_command_processing,
7 | input bit[4:0] dev_command,
8 | output bit dev_busy,
9 | input bit dev_command_data_signal,
10 | input byte dev_data,
11 |
12 | //uart out
13 | output bit uart_tx_send_byte,
14 | output byte uart_tx_byte,
15 | input bit uart_tx_active,
16 |
17 | //led
18 | output bit led_full,
19 |
20 | //Данные, которые мы анализируем
21 | input bit logic_clock,
22 | input bit[3:0] logic_data,
23 |
24 | input bit read_strobe, //Когда начинать сэмплирование
25 | input bit[8:0] data_count //Количество байт, которые надо записать
26 | );
27 |
28 | typedef enum bit [4:0] {
29 | //Очищает FIFO
30 | //Начинает запись заново
31 | //В текущий момент не работает
32 | LA_CLEAR = 5'h0,
33 |
34 | //Читаем все данные из буфера
35 | //Состоит из блоков по 48 бит = 6 байт
36 | LA_READ_ALL = 5'h1
37 | } LA_COMMANDS;
38 |
39 | //State machine для отсылки байтиков
40 | typedef enum bit [2:0] {
41 | LA_SM_IDLE = 3'h0,
42 | LA_SM_START_READ_WORD = 3'h1,
43 | LA_SM_WAIT_READ_WORD_OR_TX_START = 3'h2,
44 | LA_SM_WAIT_READ_WORD_OR_TX_START2 = 3'h3,
45 | LA_SM_WRITE_WORD = 3'h4
46 | } LA_SM;
47 |
48 | initial dev_busy = 0;
49 |
50 | byte fifo_in;
51 | byte fifo_out;
52 | bit fifo_full;
53 | bit fifo_empty;
54 | bit fifo_read_req = 0;
55 | bit fifo_write_req = 0;
56 |
57 | bit logic_clock2 = 0;
58 | bit logic_clock3 = 0;
59 |
60 | bit[3:0] logic_data2 = 0;
61 | bit[3:0] logic_data_prev = 0;
62 |
63 | LA_SM la_sm = LA_SM_IDLE;
64 |
65 | assign led_full = fifo_full;
66 |
67 | localparam bit[10:0] data_count_x2_init = 11'h600;
68 | //bit[10:0] data_count_x2 = 0;//Количество полубайт, которые надо записать
69 | bit[10:0] data_count_x2 = data_count_x2_init;
70 |
71 |
72 | logic_alanyser_fifo8_async logic_analyzer_fifo0(
73 | .data(fifo_in),
74 | .rdclk(clock),
75 | .rdreq(fifo_read_req),
76 | .wrclk(clock200mhz),
77 | .wrreq(fifo_write_req),
78 | .q(fifo_out),
79 | .rdempty(fifo_empty),
80 | .wrfull(fifo_full));
81 |
82 | bit start_word_capture = 0;
83 |
84 | //bit is_falling_clock;
85 | bit is_rising_clock;
86 | //assign is_falling_clock = logic_clock3==1'b1 && logic_clock2==1'b0;
87 | assign is_rising_clock = logic_clock3==1'b0 && logic_clock2==1'b1;
88 |
89 | bit start_flag;
90 | assign start_flag = data_count_x2>0 && logic_data_prev==4'b1111 && logic_data2==0 && start_word_capture==0;
91 |
92 | always_ff @(posedge clock200mhz)
93 | begin
94 | logic_clock2 <= logic_clock;
95 | logic_clock3 <= logic_clock2;
96 | logic_data2 <= logic_data;
97 | fifo_write_req <= 0;
98 |
99 | if(read_strobe)
100 | begin
101 | //Временно data_count_x2 <= {1'd0, data_count, 1'd0}+10'h20;//Ещё пару байт в конце отсэмплируем
102 | end
103 |
104 | if(is_rising_clock)
105 | begin
106 | //logic_data2 - это наше текущее значение, вычитанное при falling
107 | logic_data_prev <= logic_data2;
108 |
109 | if(start_flag)
110 | begin
111 | start_word_capture <= 1'b1;
112 | end
113 |
114 | if(start_word_capture || start_flag)
115 | begin
116 | if(data_count_x2[0])
117 | fifo_in[7:4] <= logic_data2;
118 | else
119 | begin
120 | fifo_in[3:0] <= logic_data2;
121 | fifo_write_req <= 1'b1;
122 | end
123 |
124 | if(data_count_x2>0)
125 | begin
126 | data_count_x2 <= data_count_x2-1'd1;
127 | end
128 | else
129 | begin
130 | start_word_capture <= 0;
131 | data_count_x2 <= data_count_x2_init; //Временно
132 | end
133 | end
134 | end
135 | end
136 |
137 | always_ff @(posedge clock)
138 | begin
139 | fifo_read_req <= 0;
140 | uart_tx_send_byte <= 0;
141 |
142 | if(dev_command_started)
143 | begin
144 | case(dev_command)
145 | LA_CLEAR:
146 | begin
147 | end
148 | LA_READ_ALL:
149 | begin
150 | la_sm <= LA_SM_START_READ_WORD;
151 | end
152 | endcase
153 | end
154 |
155 | case(la_sm)
156 | LA_SM_IDLE : ;
157 | LA_SM_START_READ_WORD:
158 | if(fifo_empty)
159 | begin
160 | la_sm <= LA_SM_IDLE;
161 | end
162 | else
163 | begin
164 | fifo_read_req <= 1'd1;
165 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START;
166 | end
167 |
168 | LA_SM_WAIT_READ_WORD_OR_TX_START:
169 | la_sm <= LA_SM_WAIT_READ_WORD_OR_TX_START2;
170 |
171 | LA_SM_WAIT_READ_WORD_OR_TX_START2:
172 | la_sm <= LA_SM_WRITE_WORD;
173 |
174 | LA_SM_WRITE_WORD:
175 | if(!uart_tx_active)
176 | begin
177 | uart_tx_byte <= fifo_out;
178 | uart_tx_send_byte <= 1'd1;
179 | la_sm <= LA_SM_START_READ_WORD;
180 | end
181 | endcase
182 | end
183 |
184 | endmodule
185 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/logic_analyzer/logic_analyzer_fifo_async.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name IP_TOOL_NAME "FIFO"
2 | set_global_assignment -name IP_TOOL_VERSION "18.1"
3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "logic_analyzer_fifo_async.v"]
5 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/logic_analyzer/logic_analyzer_fifo_async.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %FIFO%
2 | // GENERATION: STANDARD
3 | // VERSION: WM1.0
4 | // MODULE: dcfifo
5 |
6 | // ============================================================
7 | // File Name: logic_analyzer_fifo_async.v
8 | // Megafunction Name(s):
9 | // dcfifo
10 | //
11 | // Simulation Library Files(s):
12 | // altera_mf
13 | // ============================================================
14 | // ************************************************************
15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 | //
17 | // 18.1.0 Build 625 09/12/2018 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2018 Intel Corporation. All rights reserved.
22 | //Your use of Intel Corporation's design tools, logic functions
23 | //and other software and tools, and its AMPP partner logic
24 | //functions, and any output files from any of the foregoing
25 | //(including device programming or simulation files), and any
26 | //associated documentation or information are expressly subject
27 | //to the terms and conditions of the Intel Program License
28 | //Subscription Agreement, the Intel Quartus Prime License Agreement,
29 | //the Intel FPGA IP License Agreement, or other applicable license
30 | //agreement, including, without limitation, that your use is for
31 | //the sole purpose of programming logic devices manufactured by
32 | //Intel and sold by Intel or its authorized distributors. Please
33 | //refer to the applicable agreement for further details.
34 |
35 |
36 | // synopsys translate_off
37 | `timescale 1 ps / 1 ps
38 | // synopsys translate_on
39 | module logic_analyzer_fifo_async (
40 | data,
41 | rdclk,
42 | rdreq,
43 | wrclk,
44 | wrreq,
45 | q,
46 | rdempty,
47 | wrfull);
48 |
49 | input [47:0] data;
50 | input rdclk;
51 | input rdreq;
52 | input wrclk;
53 | input wrreq;
54 | output [47:0] q;
55 | output rdempty;
56 | output wrfull;
57 |
58 | wire [47:0] sub_wire0;
59 | wire sub_wire1;
60 | wire sub_wire2;
61 | wire [47:0] q = sub_wire0[47:0];
62 | wire rdempty = sub_wire1;
63 | wire wrfull = sub_wire2;
64 |
65 | dcfifo dcfifo_component (
66 | .data (data),
67 | .rdclk (rdclk),
68 | .rdreq (rdreq),
69 | .wrclk (wrclk),
70 | .wrreq (wrreq),
71 | .q (sub_wire0),
72 | .rdempty (sub_wire1),
73 | .wrfull (sub_wire2),
74 | .aclr (),
75 | .eccstatus (),
76 | .rdfull (),
77 | .rdusedw (),
78 | .wrempty (),
79 | .wrusedw ());
80 | defparam
81 | dcfifo_component.intended_device_family = "Cyclone IV E",
82 | dcfifo_component.lpm_numwords = 4096,
83 | dcfifo_component.lpm_showahead = "OFF",
84 | dcfifo_component.lpm_type = "dcfifo",
85 | dcfifo_component.lpm_width = 48,
86 | dcfifo_component.lpm_widthu = 12,
87 | dcfifo_component.overflow_checking = "ON",
88 | dcfifo_component.rdsync_delaypipe = 4,
89 | dcfifo_component.underflow_checking = "ON",
90 | dcfifo_component.use_eab = "ON",
91 | dcfifo_component.wrsync_delaypipe = 4;
92 |
93 |
94 | endmodule
95 |
96 | // ============================================================
97 | // CNX file retrieval info
98 | // ============================================================
99 | // Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
100 | // Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
101 | // Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
102 | // Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
103 | // Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0"
104 | // Retrieval info: PRIVATE: Clock NUMERIC "4"
105 | // Retrieval info: PRIVATE: Depth NUMERIC "4096"
106 | // Retrieval info: PRIVATE: Empty NUMERIC "1"
107 | // Retrieval info: PRIVATE: Full NUMERIC "1"
108 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
109 | // Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
110 | // Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1"
111 | // Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
112 | // Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
113 | // Retrieval info: PRIVATE: Optimize NUMERIC "0"
114 | // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
115 | // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
116 | // Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
117 | // Retrieval info: PRIVATE: UsedW NUMERIC "1"
118 | // Retrieval info: PRIVATE: Width NUMERIC "48"
119 | // Retrieval info: PRIVATE: dc_aclr NUMERIC "0"
120 | // Retrieval info: PRIVATE: diff_widths NUMERIC "0"
121 | // Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
122 | // Retrieval info: PRIVATE: output_width NUMERIC "48"
123 | // Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
124 | // Retrieval info: PRIVATE: rsFull NUMERIC "0"
125 | // Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
126 | // Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
127 | // Retrieval info: PRIVATE: sc_sclr NUMERIC "0"
128 | // Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
129 | // Retrieval info: PRIVATE: wsFull NUMERIC "1"
130 | // Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
131 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
132 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
133 | // Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "4096"
134 | // Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF"
135 | // Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo"
136 | // Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "48"
137 | // Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "12"
138 | // Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
139 | // Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "4"
140 | // Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
141 | // Retrieval info: CONSTANT: USE_EAB STRING "ON"
142 | // Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "4"
143 | // Retrieval info: USED_PORT: data 0 0 48 0 INPUT NODEFVAL "data[47..0]"
144 | // Retrieval info: USED_PORT: q 0 0 48 0 OUTPUT NODEFVAL "q[47..0]"
145 | // Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL "rdclk"
146 | // Retrieval info: USED_PORT: rdempty 0 0 0 0 OUTPUT NODEFVAL "rdempty"
147 | // Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
148 | // Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL "wrclk"
149 | // Retrieval info: USED_PORT: wrfull 0 0 0 0 OUTPUT NODEFVAL "wrfull"
150 | // Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
151 | // Retrieval info: CONNECT: @data 0 0 48 0 data 0 0 48 0
152 | // Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0
153 | // Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
154 | // Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0
155 | // Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
156 | // Retrieval info: CONNECT: q 0 0 48 0 @q 0 0 48 0
157 | // Retrieval info: CONNECT: rdempty 0 0 0 0 @rdempty 0 0 0 0
158 | // Retrieval info: CONNECT: wrfull 0 0 0 0 @wrfull 0 0 0 0
159 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_analyzer_fifo_async.v TRUE
160 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_analyzer_fifo_async.inc FALSE
161 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_analyzer_fifo_async.cmp FALSE
162 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_analyzer_fifo_async.bsf FALSE
163 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_analyzer_fifo_async_inst.v FALSE
164 | // Retrieval info: GEN_FILE: TYPE_NORMAL logic_analyzer_fifo_async_bb.v FALSE
165 | // Retrieval info: LIB_FILE: altera_mf
166 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/pll/pll200mhz.ppf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/pll/pll200mhz.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL"
2 | set_global_assignment -name IP_TOOL_VERSION "18.1"
3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll200mhz.v"]
5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll200mhz.ppf"]
6 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/pll/pll200mhz.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %ALTPLL%
2 | // GENERATION: STANDARD
3 | // VERSION: WM1.0
4 | // MODULE: altpll
5 |
6 | // ============================================================
7 | // File Name: pll200mhz.v
8 | // Megafunction Name(s):
9 | // altpll
10 | //
11 | // Simulation Library Files(s):
12 | // altera_mf
13 | // ============================================================
14 | // ************************************************************
15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 | //
17 | // 18.1.0 Build 625 09/12/2018 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2018 Intel Corporation. All rights reserved.
22 | //Your use of Intel Corporation's design tools, logic functions
23 | //and other software and tools, and its AMPP partner logic
24 | //functions, and any output files from any of the foregoing
25 | //(including device programming or simulation files), and any
26 | //associated documentation or information are expressly subject
27 | //to the terms and conditions of the Intel Program License
28 | //Subscription Agreement, the Intel Quartus Prime License Agreement,
29 | //the Intel FPGA IP License Agreement, or other applicable license
30 | //agreement, including, without limitation, that your use is for
31 | //the sole purpose of programming logic devices manufactured by
32 | //Intel and sold by Intel or its authorized distributors. Please
33 | //refer to the applicable agreement for further details.
34 |
35 |
36 | // synopsys translate_off
37 | `timescale 1 ps / 1 ps
38 | // synopsys translate_on
39 | module pll200mhz (
40 | inclk0,
41 | c0,
42 | locked);
43 |
44 | input inclk0;
45 | output c0;
46 | output locked;
47 |
48 | wire [4:0] sub_wire0;
49 | wire sub_wire2;
50 | wire [0:0] sub_wire5 = 1'h0;
51 | wire [0:0] sub_wire1 = sub_wire0[0:0];
52 | wire c0 = sub_wire1;
53 | wire locked = sub_wire2;
54 | wire sub_wire3 = inclk0;
55 | wire [1:0] sub_wire4 = {sub_wire5, sub_wire3};
56 |
57 | altpll altpll_component (
58 | .inclk (sub_wire4),
59 | .clk (sub_wire0),
60 | .locked (sub_wire2),
61 | .activeclock (),
62 | .areset (1'b0),
63 | .clkbad (),
64 | .clkena ({6{1'b1}}),
65 | .clkloss (),
66 | .clkswitch (1'b0),
67 | .configupdate (1'b0),
68 | .enable0 (),
69 | .enable1 (),
70 | .extclk (),
71 | .extclkena ({4{1'b1}}),
72 | .fbin (1'b1),
73 | .fbmimicbidir (),
74 | .fbout (),
75 | .fref (),
76 | .icdrclk (),
77 | .pfdena (1'b1),
78 | .phasecounterselect ({4{1'b1}}),
79 | .phasedone (),
80 | .phasestep (1'b1),
81 | .phaseupdown (1'b1),
82 | .pllena (1'b1),
83 | .scanaclr (1'b0),
84 | .scanclk (1'b0),
85 | .scanclkena (1'b1),
86 | .scandata (1'b0),
87 | .scandataout (),
88 | .scandone (),
89 | .scanread (1'b0),
90 | .scanwrite (1'b0),
91 | .sclkout0 (),
92 | .sclkout1 (),
93 | .vcooverrange (),
94 | .vcounderrange ());
95 | defparam
96 | altpll_component.bandwidth_type = "AUTO",
97 | altpll_component.clk0_divide_by = 1,
98 | altpll_component.clk0_duty_cycle = 50,
99 | altpll_component.clk0_multiply_by = 4,
100 | altpll_component.clk0_phase_shift = "0",
101 | altpll_component.compensate_clock = "CLK0",
102 | altpll_component.inclk0_input_frequency = 20000,
103 | altpll_component.intended_device_family = "Cyclone IV E",
104 | altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll200mhz",
105 | altpll_component.lpm_type = "altpll",
106 | altpll_component.operation_mode = "NORMAL",
107 | altpll_component.pll_type = "AUTO",
108 | altpll_component.port_activeclock = "PORT_UNUSED",
109 | altpll_component.port_areset = "PORT_UNUSED",
110 | altpll_component.port_clkbad0 = "PORT_UNUSED",
111 | altpll_component.port_clkbad1 = "PORT_UNUSED",
112 | altpll_component.port_clkloss = "PORT_UNUSED",
113 | altpll_component.port_clkswitch = "PORT_UNUSED",
114 | altpll_component.port_configupdate = "PORT_UNUSED",
115 | altpll_component.port_fbin = "PORT_UNUSED",
116 | altpll_component.port_inclk0 = "PORT_USED",
117 | altpll_component.port_inclk1 = "PORT_UNUSED",
118 | altpll_component.port_locked = "PORT_USED",
119 | altpll_component.port_pfdena = "PORT_UNUSED",
120 | altpll_component.port_phasecounterselect = "PORT_UNUSED",
121 | altpll_component.port_phasedone = "PORT_UNUSED",
122 | altpll_component.port_phasestep = "PORT_UNUSED",
123 | altpll_component.port_phaseupdown = "PORT_UNUSED",
124 | altpll_component.port_pllena = "PORT_UNUSED",
125 | altpll_component.port_scanaclr = "PORT_UNUSED",
126 | altpll_component.port_scanclk = "PORT_UNUSED",
127 | altpll_component.port_scanclkena = "PORT_UNUSED",
128 | altpll_component.port_scandata = "PORT_UNUSED",
129 | altpll_component.port_scandataout = "PORT_UNUSED",
130 | altpll_component.port_scandone = "PORT_UNUSED",
131 | altpll_component.port_scanread = "PORT_UNUSED",
132 | altpll_component.port_scanwrite = "PORT_UNUSED",
133 | altpll_component.port_clk0 = "PORT_USED",
134 | altpll_component.port_clk1 = "PORT_UNUSED",
135 | altpll_component.port_clk2 = "PORT_UNUSED",
136 | altpll_component.port_clk3 = "PORT_UNUSED",
137 | altpll_component.port_clk4 = "PORT_UNUSED",
138 | altpll_component.port_clk5 = "PORT_UNUSED",
139 | altpll_component.port_clkena0 = "PORT_UNUSED",
140 | altpll_component.port_clkena1 = "PORT_UNUSED",
141 | altpll_component.port_clkena2 = "PORT_UNUSED",
142 | altpll_component.port_clkena3 = "PORT_UNUSED",
143 | altpll_component.port_clkena4 = "PORT_UNUSED",
144 | altpll_component.port_clkena5 = "PORT_UNUSED",
145 | altpll_component.port_extclk0 = "PORT_UNUSED",
146 | altpll_component.port_extclk1 = "PORT_UNUSED",
147 | altpll_component.port_extclk2 = "PORT_UNUSED",
148 | altpll_component.port_extclk3 = "PORT_UNUSED",
149 | altpll_component.self_reset_on_loss_lock = "ON",
150 | altpll_component.width_clock = 5;
151 |
152 |
153 | endmodule
154 |
155 | // ============================================================
156 | // CNX file retrieval info
157 | // ============================================================
158 | // Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
159 | // Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
160 | // Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
161 | // Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
162 | // Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
163 | // Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
164 | // Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
165 | // Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
166 | // Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
167 | // Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
168 | // Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
169 | // Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
170 | // Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
171 | // Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
172 | // Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
173 | // Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "Any"
174 | // Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
175 | // Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
176 | // Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "200.000000"
177 | // Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
178 | // Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
179 | // Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
180 | // Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
181 | // Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
182 | // Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
183 | // Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
184 | // Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
185 | // Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
186 | // Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
187 | // Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
188 | // Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
189 | // Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
190 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
191 | // Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
192 | // Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
193 | // Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
194 | // Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
195 | // Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
196 | // Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
197 | // Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
198 | // Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
199 | // Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
200 | // Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
201 | // Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "200.00000000"
202 | // Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
203 | // Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
204 | // Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
205 | // Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
206 | // Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
207 | // Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
208 | // Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
209 | // Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
210 | // Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
211 | // Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
212 | // Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
213 | // Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
214 | // Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
215 | // Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
216 | // Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
217 | // Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
218 | // Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
219 | // Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll200mhz.mif"
220 | // Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
221 | // Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
222 | // Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "1"
223 | // Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
224 | // Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
225 | // Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
226 | // Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
227 | // Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
228 | // Retrieval info: PRIVATE: SPREAD_USE STRING "0"
229 | // Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
230 | // Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
231 | // Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
232 | // Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
233 | // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
234 | // Retrieval info: PRIVATE: USE_CLK0 STRING "1"
235 | // Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
236 | // Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
237 | // Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
238 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
239 | // Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
240 | // Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "1"
241 | // Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
242 | // Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "4"
243 | // Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
244 | // Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
245 | // Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
246 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
247 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
248 | // Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
249 | // Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
250 | // Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
251 | // Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
252 | // Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
253 | // Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
254 | // Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
255 | // Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
256 | // Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
257 | // Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
258 | // Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
259 | // Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
260 | // Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
261 | // Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
262 | // Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
263 | // Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
264 | // Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
265 | // Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
266 | // Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
267 | // Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
268 | // Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
269 | // Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
270 | // Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
271 | // Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
272 | // Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
273 | // Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
274 | // Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
275 | // Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
276 | // Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
277 | // Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
278 | // Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
279 | // Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
280 | // Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
281 | // Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
282 | // Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
283 | // Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
284 | // Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
285 | // Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
286 | // Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
287 | // Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
288 | // Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
289 | // Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
290 | // Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
291 | // Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "ON"
292 | // Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
293 | // Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
294 | // Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
295 | // Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
296 | // Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
297 | // Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
298 | // Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
299 | // Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
300 | // Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
301 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll200mhz.v TRUE
302 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll200mhz.ppf TRUE
303 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll200mhz.inc FALSE
304 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll200mhz.cmp FALSE
305 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll200mhz.bsf FALSE
306 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll200mhz_inst.v FALSE
307 | // Retrieval info: GEN_FILE: TYPE_NORMAL pll200mhz_bb.v FALSE
308 | // Retrieval info: LIB_FILE: altera_mf
309 | // Retrieval info: CBX_MODULE_PREFIX: ON
310 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/root_logic_analyzer.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 |
7 | module root_logic_analyzer (input clock50mhz,
8 | input uart_rx_pin,
9 | output reg uart_tx_pin,
10 |
11 | //Светодиоды
12 | output bit led110,
13 | output reg led111,
14 | output reg led114,
15 | output reg led115,
16 |
17 | input reg sd_clock,
18 | inout wire sd_cmd,
19 | inout wire[3:0] sd_data
20 | );
21 |
22 |
23 | initial led110 = 0;
24 | initial led111 = 0;
25 | initial led115 = 0;
26 |
27 | bit clock200mhz;
28 |
29 | pll200mhz pll200mhz0(
30 | .inclk0(clock50mhz),
31 | .c0(clock200mhz),
32 | .locked());
33 |
34 | localparam UART_CLKS_PER_BIT = 100;//500 000 bps --ok
35 |
36 | localparam CLOCKS_PER_TICK_1US = 50;
37 | localparam CLOCKS_PER_TICK_1MS = 50000;
38 |
39 | bit uart_rx_received;
40 | byte uart_rx_byte;
41 |
42 | bit uart_tx_send_byte = 0;
43 | bit uart_tx_active;
44 | byte uart_tx_byte;
45 |
46 | //Команды, приходящие с UART
47 | //Уже буферизированные.
48 | bit dev_command_started;
49 | bit dev_command_processing;
50 | byte dev_command;
51 | bit dev_busy;
52 | bit dev_command_data_signal;
53 | byte dev_data;
54 | bit signal_1ms;
55 | bit signal_1us;
56 |
57 | //
58 | bit dev_command_started_la;
59 | bit dev_command_processing_la;
60 | bit dev_command_data_signal_la;
61 | bit dev_busy_la;
62 | bit led_full_la;
63 | bit uart_tx_send_byte_la;
64 | byte uart_tx_byte_la;
65 |
66 |
67 | assign led114 = led_full_la;
68 | assign uart_tx_send_byte = uart_tx_send_byte_la;
69 | assign uart_tx_byte = uart_tx_byte_la;
70 |
71 | uart_rx
72 | #(.CLKS_PER_BIT(UART_CLKS_PER_BIT))
73 | uart_rx0
74 | (
75 | .i_Clock(clock50mhz),
76 | .i_Rx_Serial(uart_rx_pin),
77 | .o_Rx_DV(uart_rx_received),
78 | .o_Rx_Byte(uart_rx_byte)
79 | );
80 |
81 | uart_tx
82 | #(.CLKS_PER_BIT(UART_CLKS_PER_BIT))
83 | uart_tx0
84 | (
85 | .i_Clock(clock50mhz),
86 | .i_Tx_DV(uart_tx_send_byte),
87 | .i_Tx_Byte(uart_tx_byte),
88 | .o_Tx_Active(uart_tx_active),
89 | .o_Tx_Serial(uart_tx_pin),
90 | .o_Tx_Done()
91 | );
92 |
93 | signal_timer #(.CLOCKS_PER_TICK(CLOCKS_PER_TICK_1MS))
94 | signal_timer_1ms(
95 | .clock(clock50mhz),
96 | .signal_out(signal_1ms)
97 | );
98 |
99 | signal_timer #(.CLOCKS_PER_TICK(CLOCKS_PER_TICK_1US))
100 | signal_timer_1us(
101 | .clock(clock50mhz),
102 | .signal_out(signal_1us)
103 | );
104 |
105 | uart_rx_controller #(.TIMEOUT_MS(500))
106 | uart_rx_controller0(
107 | .clock(clock50mhz),
108 | .uart_rx_received(uart_rx_received),
109 | .uart_rx_byte(uart_rx_byte),
110 | .dev_command_started(dev_command_started),
111 | .dev_command_processing(dev_command_processing),
112 | .dev_command(dev_command),
113 | .dev_busy(dev_busy),
114 | .dev_command_data_signal(dev_command_data_signal),
115 | .dev_data(dev_data),
116 | .signal_1ms(signal_1ms)
117 | );
118 |
119 | bit write_data4_strobe;
120 | bit read_data4_strobe;
121 | bit[8:0] data4_count;
122 |
123 | bit response_start_write = 0;
124 | bit response_data_empty = 0;
125 | bit response_data_strobe = 0;
126 | bit response_data_req;
127 | byte response_data;
128 |
129 | bit read_byte_strobe;
130 | byte read_byte;
131 |
132 | //2 66 - clk
133 | //3 67 - cmd
134 | //4 68 - D0
135 | //5 69 - D1
136 | //6 70 - D2
137 | //7 71 - D3
138 | /*
139 | logic_analyzer_controller_200mhz_serial48 logic_analyzer_controller0(
140 | .clock(clock50mhz),
141 | .clock200mhz(clock200mhz),
142 | //Командный интерфейс
143 | .dev_command_started(dev_command_started_la),
144 | .dev_command_processing(dev_command_processing_la),
145 | .dev_command(dev_command[4:0]),
146 | .dev_busy(dev_busy_la),
147 | .dev_command_data_signal(dev_command_data_signal_la),
148 | .dev_data(dev_data),
149 |
150 | //uart out
151 | .uart_tx_send_byte(uart_tx_send_byte_la),
152 | .uart_tx_byte(uart_tx_byte_la),
153 | .uart_tx_active(uart_tx_active),
154 |
155 | //led
156 | .led_full(led_full_la),
157 |
158 | .logic_clock(sd_clock),
159 | .logic_serial(sd_cmd)
160 | );
161 | */
162 | /*
163 | logic_analyzer_controller_quadspi logic_analyzer_controller0(
164 | .clock(clock50mhz),
165 | .clock200mhz(clock200mhz),
166 | //Командный интерфейс
167 | .dev_command_started(dev_command_started_la),
168 | .dev_command_processing(dev_command_processing_la),
169 | .dev_command(dev_command[4:0]),
170 | .dev_busy(dev_busy_la),
171 | .dev_command_data_signal(dev_command_data_signal_la),
172 | .dev_data(dev_data),
173 |
174 | //uart out
175 | .uart_tx_send_byte(uart_tx_send_byte_la),
176 | .uart_tx_byte(uart_tx_byte_la),
177 | .uart_tx_active(uart_tx_active),
178 |
179 | //led
180 | .led_full(led_full_la),
181 |
182 | //Данные, которые мы анализируем
183 | .logic_clock(sd_clock),
184 | .logic_data(sd_data),
185 |
186 | .read_strobe(read_data4_strobe),
187 | .data_count(data4_count)
188 | );
189 | */
190 |
191 | logic_analyzer_controller_bytecopy(
192 | .clock(clock50mhz),
193 | //Командный интерфейс
194 | .dev_command_started(dev_command_started_la),
195 | .dev_command_processing(dev_command_processing_la),
196 | .dev_command(dev_command[4:0]),
197 | .dev_busy(dev_busy_la),
198 | .dev_command_data_signal(dev_command_data_signal_la),
199 | .dev_data(dev_data),
200 |
201 | //uart out
202 | .uart_tx_send_byte(uart_tx_send_byte_la),
203 | .uart_tx_byte(uart_tx_byte_la),
204 | .uart_tx_active(uart_tx_active),
205 |
206 | //led
207 | .led_full(led_full_la),
208 |
209 | //Данные, которые мы пишем
210 | .data_clock(clock200mhz),
211 | .data_strobe(read_byte_strobe),
212 | .data(read_byte)
213 | );
214 |
215 |
216 | sdio_slave sdio_slave0(
217 | .clock(clock200mhz),
218 | .sd_clock(sd_clock),
219 | .sd_serial(sd_cmd),
220 | .sd_data(sd_data),
221 |
222 | .data4_count(data4_count),
223 | .write_data4_strobe(write_data4_strobe),
224 | .read_data4_strobe(read_data4_strobe),
225 |
226 | .response_start_write(response_start_write),
227 | .response_data_empty(response_data_empty),
228 | .response_data_strobe(response_data_strobe),
229 | .response_data_req(response_data_req),
230 | .response_data(response_data),
231 |
232 | .read_byte_strobe(read_byte_strobe),
233 | .read_all_strobe(),
234 | .read_byte(read_byte),
235 | );
236 |
237 |
238 | bit[2:0] dev_command_top;
239 | assign dev_command_top = dev_command[7:5];
240 |
241 | always_comb
242 | begin
243 | dev_command_started_la = 0;
244 | dev_command_processing_la = 0;
245 | dev_command_data_signal_la = 0;
246 |
247 | dev_busy = dev_busy_la;
248 |
249 | case(dev_command_top)
250 | 3'h2:
251 | begin
252 | dev_command_started_la = dev_command_started;
253 | dev_command_processing_la = dev_command_processing;
254 | dev_command_data_signal_la = dev_command_data_signal;
255 | end
256 | default:;
257 | endcase
258 | end
259 |
260 | always_ff @(posedge clock200mhz)
261 | begin
262 | if(write_data4_strobe)
263 | led110 <= 1'd1;
264 | end
265 |
266 |
267 | //Временный код, чтобы передать данные.
268 | type_data4_count write_count = 0;
269 | always @(posedge clock200mhz)
270 | begin
271 |
272 | response_start_write <= 0;
273 | response_data_strobe <= 0;
274 | if(write_data4_strobe)
275 | begin
276 | write_count <= data4_count;
277 | response_start_write <= 1'd1;
278 | response_data_empty <= 0;
279 | end
280 |
281 | if(response_data_req)
282 | begin
283 | if(write_count>0)
284 | begin
285 | response_data <= write_count[7:0]+8'h35;
286 | response_data_strobe <= 1'd1;
287 | write_count <= write_count-1'd1;
288 | end
289 | else
290 | begin
291 | response_data_empty <= 1'd1;
292 | end
293 | end
294 |
295 | end
296 |
297 | endmodule
298 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/cis.mem:
--------------------------------------------------------------------------------
1 | //common CIS
2 | //CISTPL_MANFID (6 bytes)
3 | 20 04 c2 00 4e 47
4 |
5 | //CISTPL_FUNCE Tuple for Function 0 (6 bytes)
6 | 22 04 00
7 | 00 02 //TPLFE_FN0_BLK_SIZE (512 байт)
8 | 32 //TPLFE_MAX_TRAN_SPEED 0x32->25 MHz, 0x5A -> 50 MHz
9 |
10 | //CISTPL_END (1 byte)
11 | FF
12 |
13 | //Function 1 CIS offset D
14 |
15 | //CISTPL_MANFID (6 bytes)
16 | 20 04 c2 00 4e 47
17 |
18 | //CISTPL_FUNCE Tuple for Function 1 (44 byte) unused
19 | 22 2A 01
20 | 00 //03 TPLFE_FUNCTION_INFO
21 | 00 //04 TPLFE_STD_IO_REV
22 | 00 00 00 00 //05-08 TPLFE_CARD_PSN
23 | 00 00 00 00 //09-0C TPLFE_CSA_SIZE
24 | 00 //0D TPLFE_CSA_PROPERTY
25 | 00 01 //0E-0F TPLFE_MAX_BLK_SIZE
26 | 00 00 00 00 //10-13 TPLFE_OCR
27 | 00 //14 TPLFE_OP_MIN_PWR
28 | 00 //15 TPLFE_OP_AVG_PWR
29 | 00 //16 TPLFE_OP_MAX_PWR
30 | 00 //17 TPLFE_SB_MIN_PWR
31 | 00 //18 TPLFE_SB_AVG_PWR
32 | 00 //19 TPLFE_SB_MAX_PWR
33 | 00 00 //1A-1B TPLFE_MIN_BW
34 | 00 00 //1C-1D TPLFE_OPT_BW
35 | 00 00 //1E-1F TPLFE_ENABLE_TIMEOUT_VAL
36 | 00 00 //20-21 TPLFE_SP_AVG_PWR_3.3V
37 | 00 00 //22-23 TPLFE_SP_MAX_PWR_3.3V
38 | 00 00 //24-25 TPLFE_HP_AVG_PWR_3.3V
39 | 00 00 //26-27 TPLFE_HP_MAX_PWR_3.3V
40 | 00 00 //28-29 TPLFE_LP_AVG_PWR_3.3V
41 | 00 00 //2A-2B TPLFE_LP_MAX_PWR_3.3V
42 |
43 | //CISTPL_END (1 byte)
44 | FF
45 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sd_crc16.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 |
7 | /*
8 | Считает CRC16 пригодное для sd карты.
9 | Принимает данные 1 бит.
10 | */
11 | module sd_crc16(
12 | input bit clock,
13 | input bit clear,
14 | input bit enable, //только если enable==1 производим обработку
15 | input bit in, //1 бит данных который мы обрабатываем
16 | output bit[15:0] crc);
17 |
18 | bit xored;
19 | bit[15:0] bit_to_xor;
20 | bit[15:0] bit_shifted;
21 | assign xored = in ^ crc[15];
22 | assign bit_to_xor = {3'd0, xored, 6'd0, xored, 5'd0};
23 | assign bit_shifted = {crc[14:0], xored};
24 |
25 | always @(posedge clock)
26 | begin
27 | if (enable)
28 | crc <= bit_shifted ^ bit_to_xor;
29 |
30 | if (clear)
31 | crc <= 0;
32 | end
33 |
34 | endmodule
35 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sd_crc7.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 |
7 | /*
8 | Принимает данные по битикам.
9 | Типично первые 40 бит надо передавать в эту функцию.
10 | */
11 | module sd_crc7(
12 | input bit clock,
13 | input bit clear,
14 | input bit enable, //только если enable==1 производим обработку
15 | input bit in_bit, //Бит данных который мы обрабатываем
16 | output bit[6:0] crc);
17 |
18 | bit bit0;
19 | assign bit0 = in_bit ^ crc[6];
20 |
21 | always @(posedge clock)
22 | begin
23 | if (enable)
24 | begin
25 | crc[6] <= crc[5];
26 | crc[5] <= crc[4];
27 | crc[4] <= crc[3];
28 | crc[3] <= crc[2] ^ bit0;
29 | crc[2] <= crc[1];
30 | crc[1] <= crc[0];
31 | crc[0] <= bit0;
32 | end
33 |
34 | if (clear)
35 | crc <= 0;
36 | end
37 |
38 | endmodule
39 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sd_read_stream.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 |
7 | /*
8 | По умолчанию на sd_serial 1
9 | Если sd_serial 1->0, то началась команда.
10 | Все команды 48 бит. 38 бит полезной нагрузки, остальное - CRC и начальные 2 бита.
11 | Первый бит всегда 0.
12 | Второй бит всегда 1. Если второй бит 0, то игнорируем последующие 48 байт.
13 | */
14 |
15 | module sd_read_stream(
16 | input bit clock,
17 | input bit sd_clock,
18 | input bit sd_serial,
19 | input bit read_enabled,
20 | output bit[37:0] data,//Полезная часть данных. Валидны, когда data_strobe==1
21 | output bit data_strobe, //На 1 такт включается, когда в data корректные данные.
22 | output bit read_error //Если команда прията, но crc не совпадает (или другие обязательные биты),
23 | //то на 1 такт поднимается этот бит
24 | );
25 |
26 | //State machine для отсылки байтиков
27 | typedef enum bit [1:0] {
28 | ST_IDLE = 2'h0,
29 | ST_READ_BITS = 2'h1,
30 | ST_CHECK_CRC = 2'h2
31 | } STATE;
32 |
33 | STATE state = ST_IDLE;
34 |
35 | bit sd_clock2 = 0;
36 | bit sd_clock3 = 0;
37 | bit sd_serial2 = 0;
38 | bit sd_serial_prev = 0;
39 |
40 | bit[5:0] current_bit = 0;
41 |
42 | bit is_rising_clock;
43 | assign is_rising_clock = sd_clock3==1'b0 && sd_clock2==1'b1;
44 |
45 | bit [47:0] data48;
46 | assign data = data48[45:8];
47 |
48 | bit crc7_clear;
49 | bit crc7_enable = 0;
50 | bit crc7_bit;
51 | bit[6:0] crc7;
52 |
53 | sd_crc7 crc7m(
54 | .clock(clock),
55 | .clear(crc7_clear),
56 | .enable(crc7_enable), //только если enable==1 производим обработку
57 | .in_bit(crc7_bit), //Бит данных который мы обрабатываем
58 | .crc(crc7));
59 |
60 | bit crc_ok;
61 | bit check_ok;
62 | assign crc_ok = crc7==data48[7:1];
63 | assign check_ok = crc_ok && data48[46]==1'd1 && data48[0]==1'd1;
64 |
65 | always_ff @(posedge clock)
66 | begin
67 | sd_clock2 <= sd_clock;
68 | sd_clock3 <= sd_clock2;
69 | sd_serial2 <= sd_serial;
70 | data_strobe <= 0;
71 | read_error <= 0;
72 |
73 | if(crc7_enable)
74 | crc7_enable <= 0;
75 | if(is_rising_clock)
76 | sd_serial_prev <= sd_serial2; //st_serial2 - это наше текущее значение, вычитанное при falling
77 |
78 | if(read_enabled==0)
79 | begin
80 | state <= ST_IDLE;
81 | crc7_clear <= 1'b1;
82 | end
83 | else
84 | case(state)
85 | default:
86 | state <= ST_IDLE;
87 | ST_IDLE:
88 | if(is_rising_clock && sd_serial_prev==1'b1 && sd_serial2==0)
89 | begin
90 | current_bit <= 46;
91 | data48[47] <= 1'b0;
92 | crc7_bit <= 1'b0;
93 | crc7_clear <= 0;
94 | crc7_enable <= 1'b1;
95 | state <= ST_READ_BITS;
96 | end
97 | else
98 | begin
99 | crc7_clear <= 1'b1;
100 | end
101 |
102 | ST_READ_BITS:
103 | if(is_rising_clock)
104 | begin
105 | data48[current_bit] <= sd_serial2;
106 | crc7_bit <= sd_serial2;
107 |
108 | if(current_bit>=6'd8)
109 | crc7_enable <= 1'b1;
110 |
111 | if(current_bit>0)
112 | current_bit <= current_bit-1'b1;
113 | else
114 | state <= ST_CHECK_CRC;
115 | end
116 |
117 | ST_CHECK_CRC:
118 | begin
119 | if(check_ok)
120 | data_strobe <= 1'd1;
121 | else
122 | read_error <= 1'd1;
123 | state <= ST_IDLE;
124 | end
125 | endcase
126 | end
127 |
128 | endmodule
129 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sd_read_stream_dat.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 | /*
7 | Прочитать поток данных из SD интерфейса и передать их на FIFO для дальнейшей обработки
8 | */
9 |
10 | module sd_read_stream_dat(
11 | input bit clock,
12 | input bit sd_clock,
13 | input bit[3:0] sd_data,
14 |
15 | input bit read_strobe, //Когда начинать сэмплирование (устанавливается на 1 такт)
16 | input type_data4_count data_count, //Количество байт, которые надо прочитать
17 |
18 | output bit write_byte_strobe, //Получили байт по SD протоколу
19 | output byte byte_out, //Полученный байт
20 | output bit write_all_strobe, //Все данные получены (устанавливается на 1 такт)
21 | output bit crc_ok //Читать в тот момент, когда write_all_strobe==1
22 | );
23 |
24 | type_data4_count data_count_buf; //Количество байт, которые надо прочитать
25 | bit[3:0] crc_read_idx; //После того, как прочитали данные - читаем 16 бит CRC и сравниваем с посчитанным
26 | bit full_byte; //Устанавливается, если прочитан полный байт
27 |
28 | bit sd_clock2 = 0;
29 | bit sd_clock3 = 0;
30 |
31 | bit[3:0] sd_data2 = 0;
32 | bit[3:0] sd_data_prev = 0;
33 |
34 | bit is_rising_clock;
35 | assign is_rising_clock = sd_clock3==1'b0 && sd_clock2==1'b1;
36 |
37 | bit start_word_capture = 0;
38 | bit start_flag;
39 | assign start_flag = data_count_buf>0 && sd_data_prev==4'b1111 && sd_data2==0 && start_word_capture==0;
40 |
41 | bit read_data_complete;
42 |
43 | bit crc16_clear = 1;
44 | assign crc16_clear = read_strobe;
45 | bit crc16_enable = 0; //только если enable==1 производим обработку
46 | bit[3:0] crc16_in; //Биты данных который мы обрабатываем
47 | bit[15:0] crc16[4];
48 |
49 | sd_crc16 crc16_0(
50 | .clock(clock),
51 | .clear(crc16_clear),
52 | .enable(crc16_enable),
53 | .in(crc16_in[0]),
54 | .crc(crc16[0]));
55 |
56 | sd_crc16 crc16_1(
57 | .clock(clock),
58 | .clear(crc16_clear),
59 | .enable(crc16_enable),
60 | .in(crc16_in[1]),
61 | .crc(crc16[1]));
62 |
63 | sd_crc16 crc16_2(
64 | .clock(clock),
65 | .clear(crc16_clear),
66 | .enable(crc16_enable),
67 | .in(crc16_in[2]),
68 | .crc(crc16[2]));
69 |
70 | sd_crc16 crc16_3(
71 | .clock(clock),
72 | .clear(crc16_clear),
73 | .enable(crc16_enable),
74 | .in(crc16_in[3]),
75 | .crc(crc16[3]));
76 |
77 |
78 | always_ff @(posedge clock)
79 | begin
80 | sd_clock2 <= sd_clock;
81 | sd_clock3 <= sd_clock2;
82 | sd_data2 <= sd_data;
83 | write_byte_strobe <= 0;
84 | write_all_strobe <= 0;
85 | crc16_enable <= 0;
86 |
87 | if(read_strobe)
88 | begin
89 | data_count_buf <= data_count;
90 | crc_read_idx <= 4'hF;
91 | full_byte <= 0;
92 | start_word_capture <= 0;
93 | crc_ok <= 1'd1;
94 |
95 | read_data_complete <= 0;
96 | end
97 |
98 | if(is_rising_clock)
99 | begin
100 | sd_data_prev <= sd_data2;
101 |
102 | if(start_flag)
103 | start_word_capture <= 1'd1;
104 |
105 | if(start_word_capture)
106 | begin
107 | full_byte <= !full_byte;
108 | crc16_in <= sd_data2;
109 | crc16_enable <= !read_data_complete;
110 |
111 | if(full_byte && !read_data_complete)
112 | begin
113 | byte_out[7:4] <= crc16_in;
114 | byte_out[3:0] <= sd_data2;
115 | write_byte_strobe <= 1'd1;
116 | data_count_buf <= data_count_buf-1'd1;
117 |
118 | if(data_count_buf==9'd1)
119 | read_data_complete <= 1'd1;
120 | end
121 |
122 | if(read_data_complete)
123 | begin
124 | if( sd_data2[0]!=crc16[0][crc_read_idx]
125 | || sd_data2[1]!=crc16[1][crc_read_idx]
126 | || sd_data2[2]!=crc16[2][crc_read_idx]
127 | || sd_data2[3]!=crc16[3][crc_read_idx]
128 | )
129 | crc_ok <= 0;
130 |
131 | crc_read_idx <= crc_read_idx-1'd1;
132 | if(crc_read_idx==0)
133 | begin
134 | write_all_strobe <= 1'd1;
135 | start_word_capture<=0;
136 | end
137 | end
138 | end
139 | end
140 | end
141 |
142 |
143 | endmodule
144 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sd_response_stream.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 |
7 | /*
8 | Принимает на вход команду без crc и начальных конечных битов.
9 | На выход выдает последовательность бит.
10 | Bit 47 всегда 0 (start bit)
11 | Бит 46 всегда 0 (т.к. это ответ)
12 | Биты 7-1 CRC7
13 | Бит 0 всегда 1 (end bit)
14 |
15 | clock - у нас будет 200 МГц.
16 | sd_clock - у нас 50 МГц либо меньше
17 |
18 | Так как данные читаются по sd_clock falling,
19 | то писать их надо примерно по sd_clock rising.
20 | Можно попытаться писать по sd_clock falling + несколько тактов задержки.
21 | Собственно говоря тактов задержи и так более чем достаточно.
22 | */
23 | module sd_response_stream(
24 | input bit clock,
25 | input bit[37:0] data,//Данные которые мы посылаем, должны быть валидны всё время, пока идёт отсылка
26 | input bit data_strobe, //На 1 такт включается, когда в data корректные данные. Они должны быть корректны до окончания передачи.
27 | input bit sd_clock, //Передаем бит, когда clock falling
28 | output bit sd_serial, //Пин, через который передаются данные
29 | output bit write_enabled, //Пока передаются данные write_enabled==1 (переключение inout получается уровнем выше)
30 | output bit read_disabled
31 | );
32 |
33 | initial sd_serial = 1'd1;
34 | initial write_enabled = 0;
35 | initial read_disabled = 0;
36 |
37 | bit sd_clock2 = 0;
38 | bit sd_clock3 = 0;
39 |
40 | bit is_falling_clock;
41 | assign is_falling_clock = sd_clock3==1'b1 && sd_clock2==1'b0;
42 |
43 | bit crc7_clear = 1;
44 | assign crc7_clear = data_strobe;
45 | bit crc7_enable = 0;
46 | bit crc7_bit;
47 | bit[6:0] crc7;
48 |
49 | sd_crc7 crc7m(
50 | .clock(clock),
51 | .clear(crc7_clear),
52 | .enable(crc7_enable), //только если enable==1 производим обработку
53 | .in_bit(crc7_bit), //Бит данных который мы обрабатываем
54 | .crc(crc7));
55 |
56 | bit[47:0] data48;
57 | assign data48[45:8] = data;
58 | assign data48[7:1] = crc7;
59 | assign data48[47] = 1'b0;
60 | assign data48[46] = 1'b0;
61 | assign data48[0] = 1'b1;
62 |
63 | bit[5:0] counter = 6'h3f;
64 |
65 | bit[2:0] wait_before_write = 0;
66 | bit[1:0] wait_after_write = 0;
67 |
68 | always @(posedge clock)
69 | begin
70 | sd_clock2 <= sd_clock;
71 | sd_clock3 <= sd_clock2;
72 |
73 | if(crc7_enable)
74 | crc7_enable <= 0;
75 |
76 | if(data_strobe)
77 | begin
78 | counter <= 6'd47;
79 | wait_before_write <= 3'd7;
80 | sd_serial <= 1'd1;
81 | read_disabled <= 1'd1;
82 | end
83 | else
84 | if(is_falling_clock)
85 | begin
86 | if(wait_before_write>0)
87 | begin
88 | wait_before_write <= wait_before_write-1'd1;
89 | if(wait_before_write==3'd1)
90 | write_enabled <= 1'd1;
91 | end
92 | else
93 | begin
94 | if(counter<6'd48)
95 | begin
96 | sd_serial <= data48[counter];
97 | if(counter>=6'd8)
98 | begin
99 | crc7_enable <= 1'd1;
100 | crc7_bit <= data48[counter];
101 | end
102 |
103 | if(counter==0)
104 | wait_after_write <= 2'd3;
105 |
106 | counter <= counter-1'd1;
107 | end
108 |
109 | if(wait_after_write>0)
110 | begin
111 | wait_after_write <= wait_after_write-1'd1;
112 |
113 | if(wait_after_write==2'd2)
114 | write_enabled <= 0;
115 | if(wait_after_write==2'd1)
116 | read_disabled <= 0;
117 | end
118 | end
119 | end
120 | end
121 |
122 | endmodule
123 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sd_response_stream_dat.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 |
7 | /*
8 | Принимает на вход данные по байтам.
9 | Отправляет их по sd_data четырем проводам.
10 | Вначале пишет 0 как start bit
11 | В конце пишет crc16 и 1 как end bit.
12 | Естественно на линиях всегда 1 пока она свободна.
13 | */
14 | module sd_response_stream_dat(
15 | input bit clock,
16 |
17 | input bit start_write, //Устанавливается на один такт, после чего запускается процедура передачи данных
18 |
19 | output bit data_req, //Требуется ещё один байт данных. Не позже, чем через 2 такта должен подняться сигнал data_strobe.
20 | input bit data_empty, //Данных больше нет, переходим к отсылке CRC16
21 | input bit data_strobe, //На 1 такт включается, когда в data корректные данные. Они должны быть корректны до окончания передачи.
22 | input byte data,//Данные которые мы посылаем, должны быть валидны когда data_strobe==1
23 |
24 | //Начать отсылку CRC status (он после приёма данных по 4-м линиям должен отослаться)
25 | input bit start_send_crc_status,
26 | //crc_status==1 - positive
27 | //crc_status==0 - negative
28 | input bit crc_status,
29 |
30 | input bit sd_clock, //Передаем бит, когда clock falling
31 | output bit[3:0] sd_data, //Пин, через который передаются данные
32 | output bit write_enabled, //Пока передаются данные write_enabled==1 (переключение inout получается уровнем выше)
33 | output bit read_disabled
34 | );
35 |
36 | initial sd_data = 4'b1111;
37 | initial write_enabled = 0;
38 | initial read_disabled = 0;
39 |
40 | bit sd_clock2 = 0;
41 | bit sd_clock3 = 0;
42 |
43 | bit is_falling_clock;
44 | assign is_falling_clock = sd_clock3==1'b1 && sd_clock2==1'b0;
45 |
46 | bit crc16_clear = 1;
47 | assign crc16_clear = start_write;
48 | bit crc16_enable = 0; //только если enable==1 производим обработку
49 | bit[3:0] crc16_in; //Биты данных который мы обрабатываем
50 | bit[15:0] crc16[4];
51 |
52 | sd_crc16 crc16_0(
53 | .clock(clock),
54 | .clear(crc16_clear),
55 | .enable(crc16_enable),
56 | .in(crc16_in[0]),
57 | .crc(crc16[0]));
58 |
59 | sd_crc16 crc16_1(
60 | .clock(clock),
61 | .clear(crc16_clear),
62 | .enable(crc16_enable),
63 | .in(crc16_in[1]),
64 | .crc(crc16[1]));
65 |
66 | sd_crc16 crc16_2(
67 | .clock(clock),
68 | .clear(crc16_clear),
69 | .enable(crc16_enable),
70 | .in(crc16_in[2]),
71 | .crc(crc16[2]));
72 |
73 | sd_crc16 crc16_3(
74 | .clock(clock),
75 | .clear(crc16_clear),
76 | .enable(crc16_enable),
77 | .in(crc16_in[3]),
78 | .crc(crc16[3]));
79 |
80 | bit[2:0] wait_before_write = 0;
81 | bit[1:0] wait_after_write = 0;
82 |
83 | typedef enum bit [2:0] {
84 | //В текущий момент передачи нет.
85 | SD_STOP = 3'h0,
86 |
87 | //Пишем в sd_data нули
88 | SD_START_ZERO = 3'h1,
89 |
90 | //Пишем старшую часть битов в байте.
91 | SD_WRITE_7_4_BITS = 3'h2,
92 | //Пишем младшую часть битов в байте.
93 | SD_WRITE_3_0_BITS = 3'h3,
94 |
95 | SD_WRITE_CRC = 3'h4,
96 |
97 | //Пишем в sd_data единицы и заканчиваем передачу.
98 | SD_END_ONE = 3'h5,
99 |
100 | //Посылаем 5 бит по всем линиям одинаковые
101 | //01011 - negative
102 | //00101 - positive
103 | SD_SEND_CRC_STATUS = 3'h6
104 |
105 | } SD_COMMANDS;
106 |
107 | SD_COMMANDS command = SD_STOP;
108 |
109 | byte data_stored;
110 | bit[3:0] data_prev_stored;
111 | bit[3:0] crc_bit;
112 |
113 | bit[3:0] crc_status_bits;
114 | bit[1:0] crc_status_bits_index;
115 |
116 | always @(posedge clock)
117 | begin
118 | sd_clock2 <= sd_clock;
119 | sd_clock3 <= sd_clock2;
120 |
121 | crc16_enable <= 0;
122 | data_req <= 0;
123 |
124 | if(data_strobe)
125 | data_stored <= data;
126 |
127 | if(start_send_crc_status)
128 | begin
129 | read_disabled <= 1'd1;
130 | command <= SD_SEND_CRC_STATUS;
131 | wait_before_write <= 3'd7;
132 | wait_after_write <= 0;
133 |
134 | crc_status_bits <= crc_status?4'b0010:4'b0101;
135 | crc_status_bits_index <= 2'd3;
136 | end
137 | else
138 | if(start_write)
139 | begin
140 | data_req <= 1'd1;
141 | read_disabled <= 1'd1;
142 | command <= SD_START_ZERO;
143 | wait_before_write <= 3'd7;
144 | wait_after_write <= 0;
145 | end
146 | else
147 | if(is_falling_clock)
148 | begin
149 | if(wait_before_write>0)
150 | begin
151 | wait_before_write <= wait_before_write-1'd1;
152 | if(wait_before_write==3'd1)
153 | write_enabled <= 1'd1;
154 | end
155 | else
156 | case(command)
157 | default: ;
158 | SD_STOP: begin
159 | end
160 | SD_START_ZERO : begin
161 | sd_data <= 4'd0;
162 | command <= SD_WRITE_7_4_BITS;
163 | end
164 |
165 | SD_WRITE_7_4_BITS : begin
166 | sd_data <= data_stored[7:4];
167 | data_prev_stored <= data_stored[3:0];
168 | command <= SD_WRITE_3_0_BITS;
169 |
170 | crc16_in <= data_stored[7:4];
171 | crc16_enable <= 1'd1;
172 |
173 | data_req <= 1'd1;
174 | end
175 | SD_WRITE_3_0_BITS : begin
176 | sd_data <= data_prev_stored[3:0];
177 | crc16_in <= data_prev_stored[3:0];
178 | crc16_enable <= 1'd1;
179 |
180 | if(data_empty)
181 | begin
182 | crc_bit <= 4'd15;
183 | command <= SD_WRITE_CRC;
184 | end
185 | else
186 | command <= SD_WRITE_7_4_BITS;
187 | end
188 |
189 | SD_WRITE_CRC : begin
190 | sd_data <= {crc16[3][crc_bit], crc16[2][crc_bit], crc16[1][crc_bit], crc16[0][crc_bit]};
191 |
192 | if(crc_bit>0)
193 | crc_bit <= crc_bit-1'd1;
194 | else
195 | command <= SD_END_ONE;
196 | end
197 |
198 | SD_END_ONE: begin
199 | sd_data <= 4'b1111;
200 | command <= SD_STOP;
201 | wait_after_write <= 2'd3;
202 | end
203 |
204 | SD_SEND_CRC_STATUS : begin
205 | sd_data <= {4{crc_status_bits[crc_status_bits_index]}};
206 |
207 | if(crc_status_bits_index>0)
208 | begin
209 | crc_status_bits_index <= crc_status_bits_index-1'd1;
210 | end
211 | else
212 | begin
213 | command <= SD_END_ONE;
214 | end
215 | end
216 |
217 | endcase
218 |
219 | if(wait_after_write>0)
220 | begin
221 | wait_after_write <= wait_after_write-1'd1;
222 |
223 | if(wait_after_write==2'd2)
224 | write_enabled <= 0;
225 | if(wait_after_write==2'd1)
226 | read_disabled <= 0;
227 | end
228 | end
229 |
230 | end
231 |
232 | endmodule
233 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sd_typedef.sv:
--------------------------------------------------------------------------------
1 |
2 | //Количество байтов, которые передаются по dat линиям
3 | typedef bit [8:0] type_data4_count;
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sdio_commands_processor.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 | module sdio_commands_processor(
7 | input bit clock,
8 | //Данные прочитанные из sdio command line
9 | input bit[37:0] read_data,
10 | input bit read_data_strobe,
11 | input bit read_error,
12 |
13 | //Данные, которые следует отослать по sdio command line
14 | output bit[37:0] write_data,
15 | output bit write_data_strobe,//Отослать 38 байт и CRC
16 |
17 | //Передача/прием данных по dat0-dat3
18 | output bit write_data4_strobe, //Данные надо отсылать на хост
19 | output bit read_data4_strobe, //Данные надо принимать
20 | output type_data4_count data4_count, //Количество данных, которые следует отослать или принять по dat0-dat3
21 |
22 | input bit send_command_in_progress, //В текущий момент передаётся команда
23 | input bit send_data_in_progress //В текущий момент данные отсылаются
24 | );
25 |
26 | initial write_data_strobe = 0;
27 | initial write_data4_strobe = 0;
28 |
29 | bit[5:0] read_command_index;
30 | bit read_write_flag; //1- запись, 0 - чтение
31 | bit[2:0] read_function_number;
32 | //bit read_raw_flag;
33 | bit[17:0] read_register_address;
34 | bit[7:0] read_register_data;
35 | bit[8:0] cmd53_count; //Количество данных, которые надо прочитать, или записать
36 |
37 | assign read_command_index = read_data[37:32];
38 | assign read_write_flag = read_data[31];
39 | assign read_function_number = read_data[30:28];
40 | //assign read_raw_flag = read_data[27];
41 | assign read_register_address = read_data[25:9];
42 | assign read_register_data = read_data[7:0];
43 | assign cmd53_count = read_data[8:0];
44 |
45 | //Битики Response Flags Bit специфичные для ответа CMD52
46 | //bit 7 '0'= no error '1'= error
47 | //The CRC check of the previous command failed.
48 | bit COM_CRC_ERROR = 0;
49 |
50 | //bit 6 '0'= no error '1'= error
51 | //Command not legal for the card State.
52 | bit ILLEGAL_COMMAND = 0;
53 |
54 | //bit 5-4
55 | //00=DIS 01=CMD 02=TRN 03=RFU
56 | //DIS=Disabled: Initialize, Standby and Inactive States (card not selected)
57 | //CMD=DAT lines free: 1. Command waiting (Notransaction suspended) 2. Command waiting (All CMD53 transactions suspended)
58 | //3. Executing CMD52 in CMDState
59 | //TRN=Transfer: Command executing with data transfer using DAT[0] or DAT[3:0] lines
60 | bit[1:0] IO_CURRENT_STATE = 0;
61 | //bit 3 '0'= no error '1'= error
62 | //A general or an unknown error occurred during the operation.
63 | bit GENERAL_ERROR = 0;
64 |
65 | //Bit 1 '0'= no error '1'= error
66 | //An invalid function number was requested
67 | bit INVALID_FUNCTION_NUMBER = 0;
68 |
69 | //bit 0 '0'= no error '1'= error
70 | //ER: The command's argument was out of the allowed range for this card.
71 | //EX: Out of range occurs during execution of CMD53.
72 | bit OUT_OF_RANGE = 0;
73 |
74 | bit [7:0] cmd52_response_flags_bit;
75 | assign cmd52_response_flags_bit[7] = COM_CRC_ERROR;
76 | assign cmd52_response_flags_bit[6] = ILLEGAL_COMMAND;
77 | assign cmd52_response_flags_bit[5:4] = IO_CURRENT_STATE;
78 | assign cmd52_response_flags_bit[3] = GENERAL_ERROR;
79 | assign cmd52_response_flags_bit[2] = 0;
80 | assign cmd52_response_flags_bit[1] = INVALID_FUNCTION_NUMBER;
81 | assign cmd52_response_flags_bit[0] = OUT_OF_RANGE;
82 |
83 | byte cmd52_response_reg_data = 0;
84 |
85 | bit send_cmd52 = 0;
86 | bit send_cmd53 = 0;
87 |
88 | bit[3:0] wait_after_cmd = 0;
89 | bit read_data4_strobe_after_cmd = 0;
90 | bit write_data4_strobe_after_cmd = 0;
91 |
92 | const bit[15:0] predefined_rca = 16'h2AB1;
93 | bit[15:0] reg_rca = 0;//RCA register
94 |
95 | bit[31:0] reg_card_status;//Card Status Register
96 | assign reg_card_status[31] = OUT_OF_RANGE;
97 | assign reg_card_status[30:24] = 0;
98 | assign reg_card_status[23] = COM_CRC_ERROR;
99 | assign reg_card_status[22] = ILLEGAL_COMMAND;
100 | assign reg_card_status[21:20] = 0;
101 | assign reg_card_status[19] = GENERAL_ERROR;
102 | assign reg_card_status[18:13] = 0;
103 | assign reg_card_status[12:9] = 4'd15; //CURRENT_STATE
104 | assign reg_card_status[8:0] = 0;
105 |
106 | bit card_selected = 0;
107 |
108 | bit [15:0] block_size = 0;
109 |
110 | byte cis_array[0:63];
111 | initial $readmemh("cis.mem", cis_array, 0);
112 |
113 | bit[7:0] read_counter = 32;
114 | bit read_empty = 0;
115 |
116 | always @(posedge clock)
117 | begin
118 |
119 | write_data_strobe <= 0;
120 | write_data4_strobe <= 0;
121 | read_data4_strobe <= 0;
122 |
123 | if(send_data_in_progress)
124 | IO_CURRENT_STATE <= 2'd2;
125 | else
126 | if(card_selected)
127 | IO_CURRENT_STATE <= 2'd1;
128 | else
129 | IO_CURRENT_STATE <= 2'd0;
130 |
131 | if(wait_after_cmd > 0)
132 | wait_after_cmd <= wait_after_cmd-1'd1;
133 |
134 | if(send_cmd52)
135 | begin
136 | send_cmd52 <= 0;
137 |
138 | write_data_strobe <= 1'd1;
139 | write_data[37:32] <= 6'd52;
140 | write_data[7:0] <= cmd52_response_reg_data;
141 | write_data[15:8] <= cmd52_response_flags_bit;
142 | INVALID_FUNCTION_NUMBER <= 0;
143 | end
144 |
145 | if(send_cmd53)
146 | begin
147 | send_cmd53 <= 0;
148 | write_data_strobe <= 1'd1;
149 | write_data <= 0;
150 | write_data[37:32] <= 6'd53;
151 | //Видимо здесь будет R5 ответ (аналогично CMD52)
152 | /*
153 | if(read_data4_strobe_after_cmd) //See 4.10.1 Card Status
154 | write_data[31:0] <= 32'hd00; //CURRENT_STATE==rcv=6, READY_FOR_DATA=1
155 | else
156 | write_data[31:0] <= 32'h900; //CURRENT_STATE==tran=4, READY_FOR_DATA=1
157 | */
158 | write_data[7:0] <= cmd52_response_reg_data;
159 | write_data[15:8] <= cmd52_response_flags_bit;
160 | INVALID_FUNCTION_NUMBER <= 0;
161 | end
162 |
163 | if(wait_after_cmd==0 && !send_command_in_progress)
164 | begin
165 | if(read_data4_strobe_after_cmd)
166 | begin
167 | read_data4_strobe_after_cmd <= 0;
168 | read_data4_strobe <= 1'd1;
169 | end
170 |
171 | if(write_data4_strobe_after_cmd)
172 | begin
173 | write_data4_strobe_after_cmd <= 0;
174 | write_data4_strobe <= 1'd1;
175 | end
176 | end
177 |
178 | if(read_data_strobe)
179 | begin
180 | if(read_command_index==8'd5) //IO_SEND_OP_COND
181 | begin
182 | write_data[23:0] <= 24'h3C0000;//I/O OCR 3.0-3.4 volts 18-21 bit set
183 | write_data[24] <= 0;//S18A
184 | write_data[26:25] <= 0;//stuff bits
185 | write_data[27] <= 0; //Memory Present
186 | write_data[30:28] <= 3'd1;//Number of I/O functions
187 | write_data[31] <= 1'd1; //Set to 1 if Card is ready to operate after initialization
188 | write_data[37:32] <= 6'b111111; //Bits reserved for future use. These bits shall be set to 1.
189 |
190 | write_data_strobe <= 1'd1;
191 | end
192 |
193 | if(read_command_index==8'd3)//SEND_RELATIVE_ADDR
194 | begin
195 | write_data <= 0;
196 | write_data[13] <= GENERAL_ERROR;
197 | write_data[14] <= ILLEGAL_COMMAND;
198 | write_data[15] <= COM_CRC_ERROR;
199 | reg_rca <= predefined_rca;
200 | write_data[31:16] <= predefined_rca;
201 | write_data[37:32] <= 6'd3;
202 | write_data_strobe <= 1'd1;
203 | end
204 |
205 | if(read_command_index==8'd7)//SELECT/DESELECT_CARD
206 | begin
207 | card_selected <= (read_data[31:16]==predefined_rca);
208 |
209 | write_data <= 0;
210 | write_data[31:0] <= reg_card_status;
211 | write_data[37:32] <= 6'd7;
212 | write_data_strobe <= 1'd1;
213 | end
214 |
215 | if(read_command_index==8'd53 && read_function_number==3'd1)
216 | begin
217 | data4_count <= cmd53_count;
218 | send_cmd53 <= 1'd1;
219 |
220 | if(read_write_flag)
221 | read_data4_strobe_after_cmd <= 1'd1;
222 | else
223 | write_data4_strobe_after_cmd <= 1'd1;
224 |
225 | wait_after_cmd <= 4'd6;
226 | end
227 |
228 | if(read_command_index==8'd52)
229 | begin
230 | write_data <= 0;
231 | send_cmd52 <= 1'd1;
232 |
233 | if(read_function_number==3'd1)
234 | begin
235 | //Наши самопридуманные регистры
236 | case(read_register_address[4:0])
237 | 4'd0: begin
238 | //RX/TX
239 | cmd52_response_reg_data <= read_counter;
240 | read_counter <= read_counter+1'd1;
241 | if(read_counter==8'h7F)
242 | read_empty <= 1'd1;
243 | end
244 |
245 | 4'd1: begin
246 | //Статус данных
247 | byte STATUS_DR = 8'h01; //data ready
248 | byte STATUS_THRE = 8'h02; //transmit empty
249 | cmd52_response_reg_data <= (read_empty?8'd0:STATUS_DR) | STATUS_THRE;
250 | end
251 | default: begin
252 | INVALID_FUNCTION_NUMBER <= 1'd1;
253 | end
254 | endcase
255 | end
256 | else
257 | if(read_register_address>=17'h1000)
258 | begin
259 | cmd52_response_reg_data <= cis_array[read_register_address[5:0]];
260 | end
261 | else
262 | case(read_register_address)
263 | 17'h0: begin
264 | //CCCR/SDIO Revision
265 | //02 - CCCR/FBR defined in SDIO Version 2.00
266 | //30 - SDIO Specification Version 2.00
267 | cmd52_response_reg_data <= 8'h32;
268 | end
269 |
270 | 17'h2: begin
271 | //I/O Enable
272 | cmd52_response_reg_data <= 8'h2;
273 | end
274 | 17'h3: begin
275 | //I/O Ready
276 | cmd52_response_reg_data <= 8'h2;
277 | end
278 | 17'h4: begin
279 | //Int Enable
280 | cmd52_response_reg_data <= 0;
281 | end
282 | 17'h6: begin
283 | //I/O Abort
284 | cmd52_response_reg_data <= 0;
285 | end
286 |
287 | 17'h7: begin
288 | //I/O Abort
289 | cmd52_response_reg_data <= 8'h2; //4 bit bus width
290 | end
291 |
292 | 17'h8: begin
293 | //Card Capability
294 | const byte REG8_4BLS = 8'h80; //bit7 - 4BLS 4-bit Mode Support for Low-Speed Card
295 | const byte REG8_LSC = 8'h40; //bit6 - LSC Low-Speed Card
296 | const byte REG8_E4MI = 8'h20; //bit5 - E4MI Enable Block Gap Interrupt
297 | const byte REG8_S4MI = 8'h10; //bit4 - S4MI Support Block Gap Interrupt
298 | const byte REG8_SBS = 8'h08; //bit3 - SBS Support Bus Control
299 | const byte REG8_SRW = 8'h04; //bit2 - SRW Support Read Wait
300 | const byte REG8_SMB = 8'h02; //bit1 - SMB Support Multiple Block Transfer (CMD53)
301 | const byte REG8_SDC = 8'h01; //bit0 - SDC Support Direct Command (CMD52)
302 |
303 | cmd52_response_reg_data <= REG8_4BLS | REG8_SDC;
304 | end
305 |
306 | 17'h9: begin
307 | //CIS address 001000h
308 | //0 byte
309 | cmd52_response_reg_data <= 0;
310 | end
311 | 17'hA: begin
312 | //CIS address 001000h
313 | //1 byte
314 | cmd52_response_reg_data <= 8'h10;
315 | end
316 | 17'hB: begin
317 | //CIS address 001000h
318 | //2 byte
319 | cmd52_response_reg_data <= 0;
320 | end
321 |
322 | 17'h12: begin
323 | //Power Control
324 | cmd52_response_reg_data <= 0;
325 | end
326 |
327 | 17'h13: begin
328 | //Bus Speed Select
329 | const byte REG13_BSS2 = 8'h08;
330 | const byte REG13_BSS1 = 8'h04;
331 | const byte REG13_BSS0 = 8'h02;
332 | const byte REG13_SHS = 8'h01;
333 | //BSS[2:0] = 001b SDR25 Max Clock Frequency=50 MHz
334 |
335 | cmd52_response_reg_data <= REG13_BSS0;
336 | end
337 |
338 | //FBR registers
339 | 17'h100: begin
340 | //UART not support CSA
341 | cmd52_response_reg_data <= 8'h1;
342 | end
343 |
344 | 17'h109: begin
345 | //CIS address 00100Dh
346 | //0 byte
347 | cmd52_response_reg_data <= 8'h0D;
348 | end
349 | 17'h10A: begin
350 | //CIS address 00100Dh
351 | //1 byte
352 | cmd52_response_reg_data <= 8'h10;
353 | end
354 | 17'h10B: begin
355 | //CIS address 00100Dh
356 | //2 byte
357 | cmd52_response_reg_data <= 0;
358 | end
359 |
360 | 17'h110: begin
361 | //Block size
362 | if(read_write_flag)
363 | begin
364 | block_size[7:0] <= read_register_data;
365 | cmd52_response_reg_data <= read_register_data;
366 | end
367 | else
368 | begin
369 | cmd52_response_reg_data <= block_size[7:0];
370 | end
371 | end
372 |
373 | 17'h111: begin
374 | //Block size
375 | if(read_write_flag)
376 | begin
377 | block_size[15:8] <= read_register_data;
378 | cmd52_response_reg_data <= read_register_data;
379 | end
380 | else
381 | begin
382 | cmd52_response_reg_data <= block_size[15:8];
383 | end
384 | end
385 | default: begin
386 | INVALID_FUNCTION_NUMBER <= 1'd1;
387 | end
388 | endcase
389 | end
390 | end
391 | end
392 |
393 | endmodule
394 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/sdio_slave/sdio_slave.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 |
7 | module sdio_slave(
8 | input bit clock,
9 | input bit sd_clock,
10 | inout wire sd_serial,
11 | inout wire[3:0] sd_data,
12 |
13 | //Количество данных, которые требуется передать или принять
14 | output type_data4_count data4_count,
15 | output bit write_data4_strobe,
16 | output bit read_data4_strobe,
17 |
18 | //Интерфейс для отсылки данных по dat 4 линиям
19 | //После того, как пришел write_data4_strobe надо на 1 такт поднять response_start_write
20 | //и тем начать передачу
21 | // response_data_req - Поднимается на 1 такт, когда требуюется следующий байт response_data.
22 | // так как он требуется через достаточно продолжительное время, то задержка в 2 такта допустима
23 | // response_data_strobe выставляется на 1 такт, чтобы указать, что данные готовы (в ответ на response_data_req)
24 | // response_data_empty выставляется, если данных больше нет (в ответ на response_data_req)
25 | input bit response_start_write,
26 | input bit response_data_empty,
27 | input bit response_data_strobe,
28 | output bit response_data_req,
29 | input byte response_data,
30 |
31 | //Интерфейс для приёма данных по dat 4 линиям
32 | //read_byte_strobe прочитался байт
33 | //read_all_strobe - прочитались все data4_count байт
34 | //read_byte - байт который прочитался
35 | //read_crc_ok4 - проверка CRC подтвердила, что байты прочитались корректно (сморреть когда read_all_strobe==1)
36 | output bit read_byte_strobe,
37 | output bit read_all_strobe,
38 | output byte read_byte,
39 | output bit read_crc_ok4
40 | );
41 |
42 | bit write_enabled;
43 | bit sd_serial_out;
44 | assign sd_serial = write_enabled?sd_serial_out:1'bz;
45 |
46 | bit write_enabled4;
47 | bit[3:0] sd_data_out;
48 | assign sd_data = write_enabled4?sd_data_out:4'bz;
49 |
50 | //Данные прочитанные из sdio command line
51 | bit[37:0] read_data;
52 | bit read_data_strobe;
53 | bit read_error;
54 |
55 | //Данные, которые следует отослать по sdio command line
56 | bit[37:0] write_data;
57 | bit write_data_strobe;
58 |
59 | bit read_disabled; //Пока 1 - нельзя передавать команды
60 | bit read_disabled4; //Пока 1 - нельзя передавать данные
61 |
62 | bit start_send_crc_status = 0;
63 | bit crc_status;
64 |
65 |
66 | sd_response_stream response(
67 | .clock(clock),
68 | .data(write_data),
69 | .data_strobe(write_data_strobe),
70 | .sd_clock(sd_clock),
71 | .sd_serial(sd_serial_out),
72 | .write_enabled(write_enabled),
73 | .read_disabled(read_disabled)
74 | );
75 |
76 | sd_read_stream read(
77 | .clock(clock),
78 | .sd_clock(sd_clock),
79 | .sd_serial(sd_serial),
80 | .read_enabled(~read_disabled),
81 | .data(read_data),
82 | .data_strobe(read_data_strobe),
83 | .read_error(read_error)
84 | );
85 |
86 | sd_response_stream_dat response_dat(
87 | .clock(clock),
88 |
89 | .start_write(response_start_write),
90 |
91 | .data_req(response_data_req),
92 | .data_empty(response_data_empty),
93 | .data_strobe(response_data_strobe),
94 | .data(response_data),
95 |
96 | .start_send_crc_status(start_send_crc_status),
97 | .crc_status(crc_status),
98 |
99 | .sd_clock(sd_clock), //Передаем бит, когда clock falling
100 | .sd_data(sd_data_out), //Пин, через который передаются данные
101 | .write_enabled(write_enabled4), //Пока передаются данные write_enabled==1 (переключение inout получается уровнем выше)
102 | .read_disabled(read_disabled4)
103 | );
104 |
105 | sd_read_stream_dat read_dat(
106 | .clock(clock),
107 | .sd_clock(sd_clock),
108 | .sd_data(sd_data),
109 |
110 | .read_strobe(read_data4_strobe),
111 | .data_count(data4_count),
112 |
113 | .write_byte_strobe(read_byte_strobe),
114 | .byte_out(read_byte),
115 | .write_all_strobe(read_all_strobe),
116 | .crc_ok(read_crc_ok4)
117 | );
118 |
119 |
120 | sdio_commands_processor sdio_commands(
121 | .clock(clock),
122 |
123 | .read_data(read_data),
124 | .read_data_strobe(read_data_strobe),
125 | .read_error(read_error),
126 |
127 | .write_data(write_data),
128 | .write_data_strobe(write_data_strobe),
129 |
130 | .write_data4_strobe(write_data4_strobe),
131 | .read_data4_strobe(read_data4_strobe),
132 | .data4_count(data4_count),
133 |
134 | .send_command_in_progress(read_disabled),
135 | .send_data_in_progress(read_disabled4)
136 | );
137 |
138 |
139 | //Временный код, чтобы передать данные.
140 | always @(posedge clock)
141 | begin
142 | start_send_crc_status <= 0;
143 |
144 | //Передаём ответ, что мы приняли данные
145 | if(read_all_strobe)
146 | begin
147 | start_send_crc_status <= 1'd1;
148 | crc_status <= read_crc_ok4;
149 | end
150 | end
151 |
152 | endmodule
153 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/signal_timer.sv:
--------------------------------------------------------------------------------
1 | //Через интервал CLOCKS_PER_TICK выдает сигнал 1 на один такт
2 | module signal_timer
3 | #(parameter CLOCKS_PER_TICK = 100)
4 | (
5 | input bit clock,
6 | output bit signal_out
7 | );
8 |
9 | bit [$clog2(CLOCKS_PER_TICK):0] clock_count = 0;
10 | initial signal_out = 0;
11 |
12 | always_ff @(posedge clock)
13 | begin
14 | if(clock_count==CLOCKS_PER_TICK-1)
15 | begin
16 | clock_count <= 0;
17 | signal_out <= 1;
18 | end
19 | else
20 | begin
21 | clock_count <= clock_count+1'd1;
22 | signal_out <= 0;
23 | end
24 | end
25 |
26 | endmodule
27 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/uart/uart_rx.sv:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | // File Downloaded from http://www.nandland.com
3 | //////////////////////////////////////////////////////////////////////
4 | // This file contains the UART Receiver. This receiver is able to
5 | // receive 8 bits of serial data, one start bit, one stop bit,
6 | // and no parity bit. When receive is complete o_rx_dv will be
7 | // driven high for one clock cycle.
8 | //
9 | // Set Parameter CLKS_PER_BIT as follows:
10 | // CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
11 | // Example: 50 MHz Clock, 115200 baud UART
12 | // (50000000)/(115200) = 434
13 | // CLKS_PER_BIT should be fitted in r_Clock_Count variable
14 |
15 | module uart_rx
16 | #(parameter CLKS_PER_BIT)
17 | (
18 | input i_Clock,
19 | input i_Rx_Serial,
20 | output o_Rx_DV,
21 | output [7:0] o_Rx_Byte
22 | );
23 |
24 | localparam s_IDLE = 3'b000;
25 | localparam s_RX_START_BIT = 3'b001;
26 | localparam s_RX_DATA_BITS = 3'b010;
27 | localparam s_RX_STOP_BIT = 3'b011;
28 | localparam s_CLEANUP = 3'b100;
29 |
30 | reg r_Rx_Data_R = 1'b1;
31 | reg r_Rx_Data = 1'b1;
32 |
33 | reg [9:0] r_Clock_Count = 0;
34 | reg [2:0] r_Bit_Index = 0; //8 bits total
35 | reg [7:0] r_Rx_Byte = 0;
36 | reg r_Rx_DV = 0;
37 | reg [2:0] r_SM_Main = 0;
38 |
39 | // Purpose: Double-register the incoming data.
40 | // This allows it to be used in the UART RX Clock Domain.
41 | // (It removes problems caused by metastability)
42 | always @(posedge i_Clock)
43 | begin
44 | r_Rx_Data_R <= i_Rx_Serial;
45 | r_Rx_Data <= r_Rx_Data_R;
46 | end
47 |
48 |
49 | // Purpose: Control RX state machine
50 | always @(posedge i_Clock)
51 | begin
52 |
53 | case (r_SM_Main)
54 | s_IDLE :
55 | begin
56 | r_Rx_DV <= 1'b0;
57 | r_Clock_Count <= 0;
58 | r_Bit_Index <= 0;
59 |
60 | if (r_Rx_Data == 1'b0) // Start bit detected
61 | r_SM_Main <= s_RX_START_BIT;
62 | else
63 | r_SM_Main <= s_IDLE;
64 | end
65 |
66 | // Check middle of start bit to make sure it's still low
67 | s_RX_START_BIT :
68 | begin
69 | if (r_Clock_Count == (CLKS_PER_BIT-1)/2)
70 | begin
71 | if (r_Rx_Data == 1'b0)
72 | begin
73 | r_Clock_Count <= 0; // reset counter, found the middle
74 | r_SM_Main <= s_RX_DATA_BITS;
75 | end
76 | else
77 | r_SM_Main <= s_IDLE;
78 | end
79 | else
80 | begin
81 | r_Clock_Count <= r_Clock_Count + 1'b1;
82 | r_SM_Main <= s_RX_START_BIT;
83 | end
84 | end // case: s_RX_START_BIT
85 |
86 |
87 | // Wait CLKS_PER_BIT-1 clock cycles to sample serial data
88 | s_RX_DATA_BITS :
89 | begin
90 | if (r_Clock_Count < CLKS_PER_BIT-1)
91 | begin
92 | r_Clock_Count <= r_Clock_Count + 1'b1;
93 | r_SM_Main <= s_RX_DATA_BITS;
94 | end
95 | else
96 | begin
97 | r_Clock_Count <= 0;
98 | r_Rx_Byte[r_Bit_Index] <= r_Rx_Data;
99 |
100 | // Check if we have received all bits
101 | if (r_Bit_Index < 7)
102 | begin
103 | r_Bit_Index <= r_Bit_Index + 1'b1;
104 | r_SM_Main <= s_RX_DATA_BITS;
105 | end
106 | else
107 | begin
108 | r_Bit_Index <= 0;
109 | r_SM_Main <= s_RX_STOP_BIT;
110 | end
111 | end
112 | end // case: s_RX_DATA_BITS
113 |
114 |
115 | // Receive Stop bit. Stop bit = 1
116 | s_RX_STOP_BIT :
117 | begin
118 | // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
119 | if (r_Clock_Count < CLKS_PER_BIT-1)
120 | begin
121 | r_Clock_Count <= r_Clock_Count + 1'b1;
122 | r_SM_Main <= s_RX_STOP_BIT;
123 | end
124 | else
125 | begin
126 | r_Rx_DV <= 1'b1;
127 | r_Clock_Count <= 0;
128 | r_SM_Main <= s_CLEANUP;
129 | end
130 | end // case: s_RX_STOP_BIT
131 |
132 |
133 | // Stay here 1 clock
134 | s_CLEANUP :
135 | begin
136 | r_SM_Main <= s_IDLE;
137 | r_Rx_DV <= 1'b0;
138 | end
139 |
140 |
141 | default :
142 | r_SM_Main <= s_IDLE;
143 |
144 | endcase
145 | end
146 |
147 | assign o_Rx_DV = r_Rx_DV;
148 | assign o_Rx_Byte = r_Rx_Byte;
149 |
150 | endmodule // uart_rx
--------------------------------------------------------------------------------
/fpga/sdio_project/code/uart/uart_rx_controller.sv:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Dmitriy 'Balmer' Poskryakov
3 | * Created: 2020
4 | * License: MIT License
5 | */
6 |
7 | typedef enum bit [4:0] {
8 | RX_STATE_IDLE = 5'h0,
9 | RX_STATE_WAIT_COMMAND_BYTE,//1
10 | RX_STATE_COMMAND_BYTE,//2
11 | RX_STATE_WAIT_SIZE_BYTE,//3
12 | RX_STATE_SIZE_BYTE,//4
13 | RX_STATE_CHECK_DATA_SIZE,//5
14 | RX_STATE_START_EXECUTE_COMMAND,//6
15 | RX_STATE_WAIT_NOT_BUSY,//7
16 | RX_STATE_WAIT_DATA_BYTE,//8
17 | RX_STATE_DATA_BYTE,//9
18 | RX_STATE_BEFORE_IDLE //10
19 | } RX_STATE;
20 |
21 |
22 | module uart_rx_controller
23 | //Через такое количество времени данные из буфера будут очищенны.
24 | #(parameter TIMEOUT_MS = 10)
25 | (
26 | input clock,
27 | input bit uart_rx_received,
28 | input byte uart_rx_byte,
29 |
30 | //Команда, пересылаемая на устройство. Может пересылаться медленно.
31 | //Только один clock при начале пересылки команды на устройство
32 | output bit dev_command_started,
33 | //Все время, пока выполняется команда dev_command_processing==1
34 | output bit dev_command_processing,
35 | //Байт команды, валиден все время, пока идет передача команды на устройство
36 | output byte dev_command,
37 | //Пока dev_busy==1 - не читать следующего байта из fifo
38 | input bit dev_busy,
39 | //dev_command_data_signal==1 если валидные данные в dev_data
40 | //Данные пересылаются медленно.
41 | //Сначала проверяется, что dev_busy==0.
42 | //Запускается запрос в FIFO.
43 | //После ожидания два такта - выставляется сигнал dev_command_data_signal.
44 | output bit dev_command_data_signal,
45 | output byte dev_data,
46 |
47 | //Каждую милисекунду на 1 такт этот сигнал становится равным 1
48 | input bit signal_1ms
49 | );
50 |
51 | localparam ADDR_WIDTH = 9;
52 |
53 | initial dev_command_started = 0;
54 | initial dev_command_processing= 0;
55 | initial dev_command_data_signal = 0;
56 |
57 | bit fifo_clear = 0;
58 | bit fifo_write_request;
59 | bit fifo_read_request = 0;
60 | bit fifo_empty;
61 | bit fifo_full;
62 | bit[ADDR_WIDTH-1:0] fifo_stored_bytes;
63 | byte fifo_out_data;
64 |
65 | RX_STATE rx_state = RX_STATE_IDLE;
66 | byte size_byte;
67 | byte current_data_byte;
68 |
69 | bit [$clog2(TIMEOUT_MS):0] timeout_ms_counter = 0;
70 |
71 |
72 | assign dev_data = fifo_out_data;
73 | assign fifo_write_request = uart_rx_received;
74 |
75 | `ifdef HARDWARE_DEVICE
76 |
77 | uart_rx_fifo uart_rx_fifo0(
78 | .clock(clock),
79 | .data(uart_rx_byte),
80 | .rdreq(fifo_read_request),
81 | .sclr(fifo_clear),
82 | .wrreq(fifo_write_request),
83 | .empty(fifo_empty),
84 | .full(fifo_full),
85 | .q(fifo_out_data),
86 | .usedw(fifo_stored_bytes));
87 |
88 | `else
89 |
90 | fifo #(.ADDR_WIDTH(ADDR_WIDTH))
91 | uart_rx_fifo0(
92 | .clock(clock),
93 | .data_in(uart_rx_byte),
94 | .rdreq(fifo_read_request),
95 | .syncronous_clear(fifo_clear),
96 | .wrreq(fifo_write_request),
97 | .empty(fifo_empty),
98 | .full(fifo_full),
99 | .data_out(fifo_out_data),
100 | .usedw(fifo_stored_bytes)
101 | );
102 |
103 | `endif
104 |
105 | always_ff @(posedge clock)
106 | begin
107 | if(dev_command_started)
108 | dev_command_started <= 0;
109 |
110 | if(dev_command_data_signal)
111 | dev_command_data_signal <= 0;
112 |
113 | if(fifo_read_request)
114 | fifo_read_request <= 0;
115 |
116 | if(fifo_clear)
117 | fifo_clear <= 0;
118 |
119 | if(uart_rx_received)
120 | timeout_ms_counter <= 0;
121 |
122 | if(signal_1ms)
123 | begin
124 | timeout_ms_counter <= timeout_ms_counter+1'd1;
125 | if(timeout_ms_counter>=TIMEOUT_MS && !dev_command_processing)
126 | begin
127 | fifo_clear <= 1;
128 | rx_state <= RX_STATE_BEFORE_IDLE;
129 | timeout_ms_counter <= 0;
130 | end
131 | end
132 |
133 | case(rx_state)
134 | default : begin
135 | end
136 |
137 | RX_STATE_BEFORE_IDLE : begin
138 | rx_state <= RX_STATE_IDLE;
139 | end
140 |
141 | RX_STATE_IDLE: begin
142 | if(!fifo_empty)
143 | begin
144 | rx_state <= RX_STATE_WAIT_COMMAND_BYTE;
145 | fifo_read_request <= 1;
146 | end
147 | dev_command_processing <= 0;
148 | timeout_ms_counter <= 0;
149 | end
150 |
151 | RX_STATE_WAIT_COMMAND_BYTE : begin
152 | //Два такта проходит от fifo_read_request <=1 до получения данных в fifo_out_data
153 | rx_state <= RX_STATE_COMMAND_BYTE;
154 | end
155 |
156 | RX_STATE_COMMAND_BYTE : begin
157 | dev_command <= fifo_out_data;
158 | if(!fifo_empty)
159 | begin
160 | rx_state <= RX_STATE_WAIT_SIZE_BYTE;
161 | fifo_read_request <= 1;
162 | end
163 | end
164 |
165 | RX_STATE_WAIT_SIZE_BYTE : begin
166 | rx_state <= RX_STATE_SIZE_BYTE;
167 | end
168 |
169 | RX_STATE_SIZE_BYTE : begin
170 | size_byte <= fifo_out_data;
171 | rx_state <= RX_STATE_CHECK_DATA_SIZE;
172 | end
173 |
174 | RX_STATE_CHECK_DATA_SIZE : begin
175 | if(ADDR_WIDTH'(size_byte) <= fifo_stored_bytes && !dev_busy)
176 | begin
177 | rx_state <= RX_STATE_START_EXECUTE_COMMAND;
178 | end
179 | end
180 |
181 | RX_STATE_START_EXECUTE_COMMAND: begin
182 | dev_command_started <= 1;
183 | dev_command_processing <= 1;
184 | current_data_byte <= 0;
185 |
186 | if(size_byte==0)
187 | rx_state <= RX_STATE_IDLE;
188 | else
189 | rx_state <= RX_STATE_WAIT_NOT_BUSY;
190 |
191 | end
192 |
193 | RX_STATE_WAIT_NOT_BUSY: begin
194 | if(!dev_busy)
195 | begin
196 | fifo_read_request <= 1;
197 | rx_state <= RX_STATE_WAIT_DATA_BYTE;
198 | end
199 | end
200 |
201 | RX_STATE_WAIT_DATA_BYTE: begin
202 | fifo_read_request <= 0;
203 | rx_state <= RX_STATE_DATA_BYTE;
204 | dev_command_data_signal <= 1;
205 | end
206 |
207 |
208 | RX_STATE_DATA_BYTE : begin
209 | dev_command_data_signal <= 0;
210 | timeout_ms_counter <= 0;
211 | if(current_data_byte+1==size_byte)
212 | begin
213 | rx_state <= RX_STATE_IDLE;
214 | end
215 | else
216 | begin
217 | current_data_byte <= current_data_byte+1'd1;
218 | rx_state <= RX_STATE_WAIT_NOT_BUSY;
219 | end
220 | end
221 | endcase
222 |
223 | end
224 |
225 | endmodule
226 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/uart/uart_rx_fifo.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name IP_TOOL_NAME "FIFO"
2 | set_global_assignment -name IP_TOOL_VERSION "18.1"
3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "uart_rx_fifo.v"]
5 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/uart/uart_rx_fifo.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %FIFO%
2 | // GENERATION: STANDARD
3 | // VERSION: WM1.0
4 | // MODULE: scfifo
5 |
6 | // ============================================================
7 | // File Name: uart_rx_fifo.v
8 | // Megafunction Name(s):
9 | // scfifo
10 | //
11 | // Simulation Library Files(s):
12 | //
13 | // ============================================================
14 | // ************************************************************
15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 | //
17 | // 18.1.0 Build 625 09/12/2018 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2018 Intel Corporation. All rights reserved.
22 | //Your use of Intel Corporation's design tools, logic functions
23 | //and other software and tools, and its AMPP partner logic
24 | //functions, and any output files from any of the foregoing
25 | //(including device programming or simulation files), and any
26 | //associated documentation or information are expressly subject
27 | //to the terms and conditions of the Intel Program License
28 | //Subscription Agreement, the Intel Quartus Prime License Agreement,
29 | //the Intel FPGA IP License Agreement, or other applicable license
30 | //agreement, including, without limitation, that your use is for
31 | //the sole purpose of programming logic devices manufactured by
32 | //Intel and sold by Intel or its authorized distributors. Please
33 | //refer to the applicable agreement for further details.
34 |
35 |
36 | // synopsys translate_off
37 | `timescale 1 ps / 1 ps
38 | // synopsys translate_on
39 | module uart_rx_fifo (
40 | clock,
41 | data,
42 | rdreq,
43 | sclr,
44 | wrreq,
45 | empty,
46 | full,
47 | q,
48 | usedw);
49 |
50 | input clock;
51 | input [7:0] data;
52 | input rdreq;
53 | input sclr;
54 | input wrreq;
55 | output empty;
56 | output full;
57 | output [7:0] q;
58 | output [8:0] usedw;
59 |
60 | wire sub_wire0;
61 | wire sub_wire1;
62 | wire [7:0] sub_wire2;
63 | wire [8:0] sub_wire3;
64 | wire empty = sub_wire0;
65 | wire full = sub_wire1;
66 | wire [7:0] q = sub_wire2[7:0];
67 | wire [8:0] usedw = sub_wire3[8:0];
68 |
69 | scfifo scfifo_component (
70 | .clock (clock),
71 | .data (data),
72 | .rdreq (rdreq),
73 | .sclr (sclr),
74 | .wrreq (wrreq),
75 | .empty (sub_wire0),
76 | .full (sub_wire1),
77 | .q (sub_wire2),
78 | .usedw (sub_wire3),
79 | .aclr (),
80 | .almost_empty (),
81 | .almost_full (),
82 | .eccstatus ());
83 | defparam
84 | scfifo_component.add_ram_output_register = "OFF",
85 | scfifo_component.intended_device_family = "Cyclone IV E",
86 | scfifo_component.lpm_numwords = 512,
87 | scfifo_component.lpm_showahead = "OFF",
88 | scfifo_component.lpm_type = "scfifo",
89 | scfifo_component.lpm_width = 8,
90 | scfifo_component.lpm_widthu = 9,
91 | scfifo_component.overflow_checking = "ON",
92 | scfifo_component.underflow_checking = "ON",
93 | scfifo_component.use_eab = "ON";
94 |
95 |
96 | endmodule
97 |
98 | // ============================================================
99 | // CNX file retrieval info
100 | // ============================================================
101 | // Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0"
102 | // Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1"
103 | // Retrieval info: PRIVATE: AlmostFull NUMERIC "0"
104 | // Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1"
105 | // Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "1"
106 | // Retrieval info: PRIVATE: Clock NUMERIC "0"
107 | // Retrieval info: PRIVATE: Depth NUMERIC "512"
108 | // Retrieval info: PRIVATE: Empty NUMERIC "1"
109 | // Retrieval info: PRIVATE: Full NUMERIC "1"
110 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
111 | // Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0"
112 | // Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1"
113 | // Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0"
114 | // Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0"
115 | // Retrieval info: PRIVATE: Optimize NUMERIC "0"
116 | // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
117 | // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
118 | // Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0"
119 | // Retrieval info: PRIVATE: UsedW NUMERIC "1"
120 | // Retrieval info: PRIVATE: Width NUMERIC "8"
121 | // Retrieval info: PRIVATE: dc_aclr NUMERIC "0"
122 | // Retrieval info: PRIVATE: diff_widths NUMERIC "0"
123 | // Retrieval info: PRIVATE: msb_usedw NUMERIC "0"
124 | // Retrieval info: PRIVATE: output_width NUMERIC "8"
125 | // Retrieval info: PRIVATE: rsEmpty NUMERIC "1"
126 | // Retrieval info: PRIVATE: rsFull NUMERIC "0"
127 | // Retrieval info: PRIVATE: rsUsedW NUMERIC "0"
128 | // Retrieval info: PRIVATE: sc_aclr NUMERIC "0"
129 | // Retrieval info: PRIVATE: sc_sclr NUMERIC "1"
130 | // Retrieval info: PRIVATE: wsEmpty NUMERIC "0"
131 | // Retrieval info: PRIVATE: wsFull NUMERIC "1"
132 | // Retrieval info: PRIVATE: wsUsedW NUMERIC "0"
133 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
134 | // Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF"
135 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
136 | // Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "512"
137 | // Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF"
138 | // Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo"
139 | // Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8"
140 | // Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "9"
141 | // Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON"
142 | // Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON"
143 | // Retrieval info: CONSTANT: USE_EAB STRING "ON"
144 | // Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock"
145 | // Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
146 | // Retrieval info: USED_PORT: empty 0 0 0 0 OUTPUT NODEFVAL "empty"
147 | // Retrieval info: USED_PORT: full 0 0 0 0 OUTPUT NODEFVAL "full"
148 | // Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
149 | // Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq"
150 | // Retrieval info: USED_PORT: sclr 0 0 0 0 INPUT NODEFVAL "sclr"
151 | // Retrieval info: USED_PORT: usedw 0 0 9 0 OUTPUT NODEFVAL "usedw[8..0]"
152 | // Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq"
153 | // Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0
154 | // Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0
155 | // Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0
156 | // Retrieval info: CONNECT: @sclr 0 0 0 0 sclr 0 0 0 0
157 | // Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0
158 | // Retrieval info: CONNECT: empty 0 0 0 0 @empty 0 0 0 0
159 | // Retrieval info: CONNECT: full 0 0 0 0 @full 0 0 0 0
160 | // Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0
161 | // Retrieval info: CONNECT: usedw 0 0 9 0 @usedw 0 0 9 0
162 | // Retrieval info: GEN_FILE: TYPE_NORMAL uart_rx_fifo.v TRUE
163 | // Retrieval info: GEN_FILE: TYPE_NORMAL uart_rx_fifo.inc FALSE
164 | // Retrieval info: GEN_FILE: TYPE_NORMAL uart_rx_fifo.cmp FALSE
165 | // Retrieval info: GEN_FILE: TYPE_NORMAL uart_rx_fifo.bsf FALSE
166 | // Retrieval info: GEN_FILE: TYPE_NORMAL uart_rx_fifo_inst.v FALSE
167 | // Retrieval info: GEN_FILE: TYPE_NORMAL uart_rx_fifo_bb.v FALSE
168 |
--------------------------------------------------------------------------------
/fpga/sdio_project/code/uart/uart_tx.sv:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////
2 | // File Downloaded from http://www.nandland.com
3 | //////////////////////////////////////////////////////////////////////
4 | // This file contains the UART Transmitter. This transmitter is able
5 | // to transmit 8 bits of serial data, one start bit, one stop bit,
6 | // and no parity bit. When transmit is complete o_Tx_done will be
7 | // driven high for one clock cycle.
8 | //
9 | // Set Parameter CLKS_PER_BIT as follows:
10 | // CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
11 | // Example: 10 MHz Clock, 115200 baud UART
12 | // (10000000)/(115200) = 87
13 |
14 | module uart_tx
15 | #(parameter CLKS_PER_BIT)
16 | (
17 | input i_Clock,
18 | input i_Tx_DV,
19 | input [7:0] i_Tx_Byte,
20 | output o_Tx_Active,
21 | output reg o_Tx_Serial,
22 | output o_Tx_Done
23 | );
24 |
25 | localparam s_IDLE = 3'b000;
26 | localparam s_TX_START_BIT = 3'b001;
27 | localparam s_TX_DATA_BITS = 3'b010;
28 | localparam s_TX_STOP_BIT = 3'b011;
29 | localparam s_CLEANUP = 3'b100;
30 |
31 | reg [2:0] r_SM_Main = 0;
32 | reg [9:0] r_Clock_Count = 0;
33 | reg [2:0] r_Bit_Index = 0;
34 | reg [7:0] r_Tx_Data = 0;
35 | reg r_Tx_Done = 0;
36 | reg r_Tx_Active = 0;
37 |
38 | always @(posedge i_Clock)
39 | begin
40 |
41 | case (r_SM_Main)
42 | s_IDLE :
43 | begin
44 | o_Tx_Serial <= 1'b1; // Drive Line High for Idle
45 | r_Tx_Done <= 1'b0;
46 | r_Clock_Count <= 0;
47 | r_Bit_Index <= 0;
48 | r_Tx_Active <= 1'b0; //balmer
49 |
50 | if (i_Tx_DV == 1'b1)
51 | begin
52 | r_Tx_Active <= 1'b1;
53 | r_Tx_Data <= i_Tx_Byte;
54 | r_SM_Main <= s_TX_START_BIT;
55 | end
56 | else
57 | r_SM_Main <= s_IDLE;
58 | end // case: s_IDLE
59 |
60 |
61 | // Send out Start Bit. Start bit = 0
62 | s_TX_START_BIT :
63 | begin
64 | o_Tx_Serial <= 1'b0;
65 |
66 | // Wait CLKS_PER_BIT-1 clock cycles for start bit to finish
67 | if (r_Clock_Count < CLKS_PER_BIT-1)
68 | begin
69 | r_Clock_Count <= r_Clock_Count + 1'b1;
70 | r_SM_Main <= s_TX_START_BIT;
71 | end
72 | else
73 | begin
74 | r_Clock_Count <= 0;
75 | r_SM_Main <= s_TX_DATA_BITS;
76 | end
77 | end // case: s_TX_START_BIT
78 |
79 |
80 | // Wait CLKS_PER_BIT-1 clock cycles for data bits to finish
81 | s_TX_DATA_BITS :
82 | begin
83 | o_Tx_Serial <= r_Tx_Data[r_Bit_Index];
84 |
85 | if (r_Clock_Count < CLKS_PER_BIT-1)
86 | begin
87 | r_Clock_Count <= r_Clock_Count + 1'b1;
88 | r_SM_Main <= s_TX_DATA_BITS;
89 | end
90 | else
91 | begin
92 | r_Clock_Count <= 0;
93 |
94 | // Check if we have sent out all bits
95 | if (r_Bit_Index < 7)
96 | begin
97 | r_Bit_Index <= r_Bit_Index + 1'b1;
98 | r_SM_Main <= s_TX_DATA_BITS;
99 | end
100 | else
101 | begin
102 | r_Bit_Index <= 0;
103 | r_SM_Main <= s_TX_STOP_BIT;
104 | end
105 | end
106 | end // case: s_TX_DATA_BITS
107 |
108 |
109 | // Send out Stop bit. Stop bit = 1
110 | s_TX_STOP_BIT :
111 | begin
112 | o_Tx_Serial <= 1'b1;
113 |
114 | // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
115 | if (r_Clock_Count < CLKS_PER_BIT-1+3)
116 | begin
117 | r_Clock_Count <= r_Clock_Count + 1'b1;
118 | r_SM_Main <= s_TX_STOP_BIT;
119 | end
120 | else
121 | begin
122 | r_Tx_Done <= 1'b1;
123 | r_Clock_Count <= 0;
124 | r_SM_Main <= s_CLEANUP;
125 | //r_Tx_Active <= 1'b0; //balmer
126 | end
127 | end // case: s_Tx_STOP_BIT
128 |
129 |
130 | // Stay here 1 clock
131 | s_CLEANUP :
132 | begin
133 | r_Tx_Done <= 1'b1;
134 | r_SM_Main <= s_IDLE;
135 | end
136 |
137 |
138 | default :
139 | r_SM_Main <= s_IDLE;
140 |
141 | endcase
142 | end
143 |
144 | assign o_Tx_Active = r_Tx_Active;
145 | assign o_Tx_Done = r_Tx_Done;
146 |
147 | endmodule
148 |
--------------------------------------------------------------------------------
/fpga/sdio_project/sdio_project.qpf:
--------------------------------------------------------------------------------
1 | # -------------------------------------------------------------------------- #
2 | #
3 | # Copyright (C) 2017 Intel Corporation. All rights reserved.
4 | # Your use of Intel Corporation's design tools, logic functions
5 | # and other software and tools, and its AMPP partner logic
6 | # functions, and any output files from any of the foregoing
7 | # (including device programming or simulation files), and any
8 | # associated documentation or information are expressly subject
9 | # to the terms and conditions of the Intel Program License
10 | # Subscription Agreement, the Intel Quartus Prime License Agreement,
11 | # the Intel FPGA IP License Agreement, or other applicable license
12 | # agreement, including, without limitation, that your use is for
13 | # the sole purpose of programming logic devices manufactured by
14 | # Intel and sold by Intel or its authorized distributors. Please
15 | # refer to the applicable agreement for further details.
16 | #
17 | # -------------------------------------------------------------------------- #
18 | #
19 | # Quartus Prime
20 | # Version 17.1.1 Internal Build 593 12/11/2017 SJ Lite Edition
21 | # Date created = 22:46:45 October 24, 2018
22 | #
23 | # -------------------------------------------------------------------------- #
24 |
25 | QUARTUS_VERSION = "17.1"
26 | DATE = "22:46:45 October 24, 2018"
27 |
28 | # Revisions
29 |
30 | PROJECT_REVISION = "sdio_project"
31 |
--------------------------------------------------------------------------------
/fpga/sdio_project/sdio_project.qsf:
--------------------------------------------------------------------------------
1 | # -------------------------------------------------------------------------- #
2 | #
3 | # Copyright (C) 2017 Intel Corporation. All rights reserved.
4 | # Your use of Intel Corporation's design tools, logic functions
5 | # and other software and tools, and its AMPP partner logic
6 | # functions, and any output files from any of the foregoing
7 | # (including device programming or simulation files), and any
8 | # associated documentation or information are expressly subject
9 | # to the terms and conditions of the Intel Program License
10 | # Subscription Agreement, the Intel Quartus Prime License Agreement,
11 | # the Intel FPGA IP License Agreement, or other applicable license
12 | # agreement, including, without limitation, that your use is for
13 | # the sole purpose of programming logic devices manufactured by
14 | # Intel and sold by Intel or its authorized distributors. Please
15 | # refer to the applicable agreement for further details.
16 | #
17 | # -------------------------------------------------------------------------- #
18 | #
19 | # Quartus Prime
20 | # Version 17.1.1 Internal Build 593 12/11/2017 SJ Lite Edition
21 | # Date created = 22:46:45 October 24, 2018
22 | #
23 | # -------------------------------------------------------------------------- #
24 | #
25 | # Notes:
26 | #
27 | # 1) The default values for assignments are stored in the file:
28 | # test_my_board_assignment_defaults.qdf
29 | # If this file doesn't exist, see file:
30 | # assignment_defaults.qdf
31 | #
32 | # 2) Altera recommends that you do not modify this file. This
33 | # file is updated automatically by the Quartus Prime software
34 | # and any changes you make may be lost or overwritten.
35 | #
36 | # -------------------------------------------------------------------------- #
37 |
38 |
39 | set_global_assignment -name FAMILY "Cyclone IV E"
40 | set_global_assignment -name DEVICE EP4CE10E22C6
41 | set_global_assignment -name TOP_LEVEL_ENTITY root_logic_analyzer
42 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.1.1
43 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "22:46:45 OCTOBER 24, 2018"
44 | set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition"
45 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
46 | set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
47 | set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
48 | set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP
49 | set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
50 | set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 6
51 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
52 | set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V
53 | set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (SystemVerilog)"
54 | set_global_assignment -name EDA_TIME_SCALE "1 ps" -section_id eda_simulation
55 | set_global_assignment -name EDA_OUTPUT_DATA_FORMAT "SYSTEMVERILOG HDL" -section_id eda_simulation
56 | set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
57 | set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
58 | set_location_assignment PIN_23 -to clock50mhz
59 | set_location_assignment PIN_110 -to led110
60 | set_location_assignment PIN_111 -to led111
61 | set_location_assignment PIN_114 -to led114
62 | set_location_assignment PIN_115 -to led115
63 | set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
64 | set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
65 | set_location_assignment PIN_38 -to uart_rx_pin
66 | set_location_assignment PIN_39 -to uart_tx_pin
67 |
68 | set_global_assignment -name NUM_PARALLEL_PROCESSORS 2
69 |
70 | set_location_assignment PIN_66 -to sd_clock
71 | set_location_assignment PIN_67 -to sd_cmd
72 | set_location_assignment PIN_68 -to sd_data[0]
73 | set_location_assignment PIN_69 -to sd_data[1]
74 | set_location_assignment PIN_70 -to sd_data[2]
75 | set_location_assignment PIN_71 -to sd_data[3]
76 | set_global_assignment -name VERILOG_MACRO "HARDWARE_DEVICE="
77 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
78 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
79 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
80 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clock50mhz
81 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to led110
82 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to led111
83 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to led114
84 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to led115
85 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart_rx_pin
86 | set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart_tx_pin
87 | set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to sd_clock
88 | set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to sd_cmd
89 | set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to sd_data[0]
90 | set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to sd_data[1]
91 | set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to sd_data[2]
92 | set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to sd_data[3]
93 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to sd_data[3]
94 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to sd_data[2]
95 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to sd_data[1]
96 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to sd_data[0]
97 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to sd_cmd
98 | set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to sd_clock
99 | set_global_assignment -name SDC_FILE sdio_project.sdc
100 | set_global_assignment -name QIP_FILE code/uart/uart_rx_fifo.qip
101 | set_global_assignment -name QIP_FILE code/pll/pll200mhz.qip
102 | set_global_assignment -name QIP_FILE code/logic_analyzer/logic_analyzer_fifo_async.qip
103 | set_global_assignment -name QIP_FILE code/logic_analyzer/logic_alanyser_fifo8_async.qip
104 | set_global_assignment -name CDF_FILE write_to_flash.cdf
105 | set_global_assignment -name SYSTEMVERILOG_FILE code/root_logic_analyzer.sv
106 | set_global_assignment -name SYSTEMVERILOG_FILE code/logic_analyzer/logic_analyzer_controller_200mhz_serial48.sv
107 | set_global_assignment -name SYSTEMVERILOG_FILE code/logic_analyzer/logic_analyzer_controller_quadspi.sv
108 | set_global_assignment -name SYSTEMVERILOG_FILE code/uart/uart_tx.sv
109 | set_global_assignment -name SYSTEMVERILOG_FILE code/uart/uart_rx.sv
110 | set_global_assignment -name SYSTEMVERILOG_FILE code/uart/uart_rx_controller.sv
111 | set_global_assignment -name SYSTEMVERILOG_FILE code/signal_timer.sv
112 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sdio_slave.sv
113 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sd_crc7.sv
114 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sd_crc16.sv
115 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sd_read_stream.sv
116 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sd_response_stream.sv
117 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sd_response_stream_dat.sv
118 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sdio_commands_processor.sv
119 |
120 | set_instance_assignment -name IO_STANDARD "3.0-V LVTTL" -to sd_data
121 |
122 |
123 |
124 |
125 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sd_read_stream_dat.sv
126 | set_global_assignment -name SYSTEMVERILOG_FILE code/sdio_slave/sd_typedef.sv
127 | set_global_assignment -name SYSTEMVERILOG_FILE code/logic_analyzer/logic_analyzer_controller_bytecopy.sv
128 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
--------------------------------------------------------------------------------
/fpga/sdio_project/sdio_project.sdc:
--------------------------------------------------------------------------------
1 | ## Generated SDC file "test_asm18.out.sdc"
2 |
3 | ## Copyright (C) 2016 Intel Corporation. All rights reserved.
4 | ## Your use of Intel Corporation's design tools, logic functions
5 | ## and other software and tools, and its AMPP partner logic
6 | ## functions, and any output files from any of the foregoing
7 | ## (including device programming or simulation files), and any
8 | ## associated documentation or information are expressly subject
9 | ## to the terms and conditions of the Intel Program License
10 | ## Subscription Agreement, the Intel Quartus Prime License Agreement,
11 | ## the Intel MegaCore Function License Agreement, or other
12 | ## applicable license agreement, including, without limitation,
13 | ## that your use is for the sole purpose of programming logic
14 | ## devices manufactured by Intel and sold by Intel or its
15 | ## authorized distributors. Please refer to the applicable
16 | ## agreement for further details.
17 |
18 |
19 | ## VENDOR "Altera"
20 | ## PROGRAM "Quartus Prime"
21 | ## VERSION "Version 16.1.0 Build 196 10/24/2016 SJ Lite Edition"
22 |
23 | ## DATE "Tue Feb 13 07:07:50 2018"
24 |
25 | ##
26 | ## DEVICE "EP4CE10E22C8"
27 | ##
28 |
29 |
30 | #**************************************************************
31 | # Time Information
32 | #**************************************************************
33 |
34 | set_time_format -unit ns -decimal_places 3
35 |
36 |
37 |
38 | #**************************************************************
39 | # Create Clock
40 | #**************************************************************
41 |
42 | create_clock -name {clock50mhz} -period 20.000 -waveform { 0.000 10.000 } [get_ports clock50mhz]
43 | #create_generated_clock
44 | derive_pll_clocks
45 |
46 |
47 | #**************************************************************
48 | # Create Generated Clock
49 | #**************************************************************
50 |
51 |
52 |
53 | #**************************************************************
54 | # Set Clock Latency
55 | #**************************************************************
56 |
57 |
58 |
59 | #**************************************************************
60 | # Set Clock Uncertainty
61 | #**************************************************************
62 |
63 |
64 |
65 | #**************************************************************
66 | # Set Input Delay
67 | #**************************************************************
68 |
69 |
70 |
71 | #**************************************************************
72 | # Set Output Delay
73 | #**************************************************************
74 |
75 |
76 |
77 | #**************************************************************
78 | # Set Clock Groups
79 | #**************************************************************
80 |
81 |
82 |
83 | #**************************************************************
84 | # Set False Path
85 | #**************************************************************
86 |
87 |
88 |
89 | #**************************************************************
90 | # Set Multicycle Path
91 | #**************************************************************
92 |
93 |
94 |
95 | #**************************************************************
96 | # Set Maximum Delay
97 | #**************************************************************
98 |
99 |
100 |
101 | #**************************************************************
102 | # Set Minimum Delay
103 | #**************************************************************
104 |
105 |
106 |
107 | #**************************************************************
108 | # Set Input Transition
109 | #**************************************************************
110 |
111 |
--------------------------------------------------------------------------------
/fpga/sdio_project/write_to_flash.cdf:
--------------------------------------------------------------------------------
1 | /* Quartus Prime Version 18.1.0 Build 625 09/12/2018 SJ Lite Edition */
2 | JedecChain;
3 | FileRevision(JESD32A);
4 | DefaultMfr(6E);
5 |
6 | P ActionCode(Cfg)
7 | Device PartName(EP4CE10) Path("/home/balmer/radio/altera/projects/sdio_linux_fpga/fpga/sdio_project/output_files/") File("output_file.jic") MfrSpec(OpMask(1) SEC_Device(EPCS16) Child_OpMask(1 1));
8 |
9 | ChainEnd;
10 |
11 | AlteraBegin;
12 | ChainType(JTAG);
13 | AlteraEnd;
14 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/Makefile_obj:
--------------------------------------------------------------------------------
1 | CPPFLAGS += -MMD -MP
2 | CPPFLAGS += -g # defug info
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/crc16.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | inline uint16_t crc16_1bit(uint16_t prev, bool bit)
6 | {
7 | uint16_t inv = (bit?1:0) ^ ((prev>>15)&1);
8 |
9 | return ((prev<<1)|inv)^((inv<<5)|(inv<<12));
10 | }
11 |
12 | inline uint16_t crc16_4bit(uint16_t prev, uint8_t byte)
13 | {
14 | for(int i=0; i<4; i++)
15 | prev = crc16_1bit(prev, (byte&(1<& bytes)
28 | {
29 | uint16_t prev = 0;
30 | for(uint8_t b : bytes)
31 | prev = crc16_8bit(prev, b);
32 | return prev;
33 | }
34 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/makefile:
--------------------------------------------------------------------------------
1 | VERILATOR_FLAGS =
2 | # Generate C++ in executable form
3 | VERILATOR_FLAGS += -cc --exe
4 | # Generate makefile dependencies (not shown as complicates the Makefile)
5 | #VERILATOR_FLAGS += -MMD
6 | # Optimize
7 | #VERILATOR_FLAGS += -O2 -x-assign 0
8 | # Warn abount lint issues; may not want this on less solid designs
9 | VERILATOR_FLAGS += -Wall
10 | # Make waveforms
11 | VERILATOR_FLAGS += --trace
12 | # Check SystemVerilog assertions
13 | VERILATOR_FLAGS += --assert
14 | # Generate coverage analysis
15 | VERILATOR_FLAGS += --coverage
16 | # Run Verilator in debug mode
17 | #VERILATOR_FLAGS += --debug
18 | # Add this trace to get a backtrace in gdb
19 | VERILATOR_FLAGS += --gdbbt
20 |
21 |
22 | build:
23 | @mkdir -p logs
24 | verilator $(VERILATOR_FLAGS) --top-module sd_crc16 ../../sdio_project/code/sdio_slave/sd_crc16.sv sim_main.cpp tests.cpp
25 | $(MAKE) -j -C obj_dir -f Vsd_crc16.mk Vsd_crc16 -f ../Makefile_obj
26 |
27 | run:
28 | obj_dir/Vsd_read_stream +trace
29 |
30 | clean:
31 | -rm -rf obj_dir logs
32 |
33 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/sd_crc16.cflags:
--------------------------------------------------------------------------------
1 | -std=c17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/sd_crc16.config:
--------------------------------------------------------------------------------
1 | // Add predefined macros for your project here. For example:
2 | // #define THE_ANSWER 42
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/sd_crc16.creator:
--------------------------------------------------------------------------------
1 | [General]
2 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/sd_crc16.cxxflags:
--------------------------------------------------------------------------------
1 | -std=c++17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/sd_crc16.files:
--------------------------------------------------------------------------------
1 | crc16.h
2 | tests.cpp
3 | tests.h
4 | obj_dir/Vspi_tx.cpp
5 | obj_dir/Vspi_tx.h
6 | obj_dir/Vspi_tx__ALLcls.cpp
7 | obj_dir/Vspi_tx__ALLsup.cpp
8 | obj_dir/Vspi_tx__Syms.cpp
9 | obj_dir/Vspi_tx__Syms.h
10 | obj_dir/Vspi_tx__Trace.cpp
11 | obj_dir/Vspi_tx__Trace__Slow.cpp
12 | sim_main.cpp
13 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/sd_crc16.includes:
--------------------------------------------------------------------------------
1 | obj_dir
2 | .
3 | /home/balmer/radio/altera/soft/verilator/verilator/include
4 |
5 | /usr/include
6 | /usr/include/c++/7
7 | /usr/include/x86_64-linux-gnu
8 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/sim_main.cpp:
--------------------------------------------------------------------------------
1 | #include "verilated.h"
2 | #include
3 |
4 | #include "tests.h"
5 | #include
6 |
7 | // Current simulation time (64-bit unsigned)
8 | vluint64_t main_time = 0;
9 | // Called by $time in Verilog
10 | double sc_time_stamp() {
11 | return main_time; // Note does conversion to real, to match SystemC
12 | }
13 |
14 | int main(int argc, char** argv, char** env)
15 | {
16 | Verilated::commandArgs(argc, argv);
17 | Vsd_crc16* top = new Vsd_crc16;
18 | // If verilator was invoked with --trace argument,
19 | // and if at run time passed the +trace argument, turn on tracing
20 | VerilatedVcdC* tfp = NULL;
21 | const char* flag = Verilated::commandArgsPlusMatch("trace");
22 | if (flag && 0==strcmp(flag, "+trace")) {
23 | Verilated::traceEverOn(true); // Verilator must compute traced signals
24 | VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
25 | tfp = new VerilatedVcdC;
26 | top->trace(tfp, 99); // Trace 99 levels of hierarchy
27 | Verilated::mkdir("logs");
28 | tfp->open("logs/vlt_dump.vcd"); // Open the dump file
29 | }
30 |
31 | top->clock = 0;
32 | top->clear = 1;
33 | top->enable = 0;
34 | top->in = 0;
35 |
36 | std::vector> test;
37 | test.push_back(std::make_shared(20));
38 | test.push_back(std::make_shared());
39 |
40 |
41 | int current_test = -1;
42 | bool next_test = true;
43 | bool test_failed = false;
44 |
45 | while (!Verilated::gotFinish())
46 | {
47 | if(next_test)
48 | {
49 | current_test++;
50 | if(current_test>=test.size())
51 | break;
52 | next_test = false;
53 | test[current_test]->init(top);
54 | test[current_test]->start();
55 | }
56 |
57 | top->clock = (main_time&1)?1:0;
58 | test[current_test]->beforeEval();
59 |
60 | top->eval();
61 | // Dump trace data for this cycle
62 | if (tfp) tfp->dump (main_time);
63 |
64 | if(!test[current_test]->afterEval())
65 | {
66 | if(test[current_test]->fail())
67 | {
68 | printf("---- Failed\n");
69 | test_failed = true;
70 | break;
71 | }
72 |
73 | printf("---- Succeeded\n");
74 | next_test = true;
75 | }
76 |
77 |
78 | main_time++; // Time passes...
79 | }
80 |
81 | if(test_failed)
82 | printf("Tests failed\n");
83 | else
84 | printf("All tests succeeded\n");
85 |
86 |
87 | // Final model cleanup
88 | top->final();
89 |
90 | // Close trace if opened
91 | if (tfp) { tfp->close(); tfp = NULL; }
92 |
93 | delete top;
94 | exit(test_failed?1:0);
95 | }
96 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/tests.cpp:
--------------------------------------------------------------------------------
1 | #include "tests.h"
2 |
3 | #include "../sd_response_stream/crc7.h"
4 |
5 | //Global time counter
6 | //Время идет по пол такта.
7 | //Тоесть за один такт main_time изменяется на 2
8 | //Несетные - clock = 1, четные clock = 0
9 | extern vluint64_t main_time;
10 | bool clockRising() { return (main_time&1)==1; }
11 | bool clockFalling() { return (main_time&1)==0; }
12 | //bool clockSck() { return (main_time/2)%32==1; }
13 | //bool clockSck() { return (main_time/2)%4==1; }
14 | bool clockSck() { return (main_time/2)%2==1; }
15 |
16 | VerilogTest::VerilogTest()
17 | {
18 | }
19 |
20 | VerilogTest::~VerilogTest()
21 | {
22 | }
23 |
24 | void VerilogTest::init(Vsd_crc16 *top)
25 | {
26 | this->top = top;
27 | }
28 |
29 | TestClear::TestClear(vluint64_t duration)
30 | : duration(duration)
31 | {
32 |
33 | }
34 |
35 |
36 | void TestClear::start()
37 | {
38 | start_time = main_time;
39 | printf("TestClear started");
40 | top->clear = 1;
41 | top->enable = 0;
42 | top->crc = 0x1234;
43 | }
44 |
45 | void TestClear::beforeEval()
46 | {
47 | }
48 |
49 | bool TestClear::afterEval()
50 | {
51 | if(!clockRising())
52 | return true;
53 |
54 | if(top->crc!=0)
55 | {
56 | printf("TestClear crc not zero!\n");
57 | _fail = true;
58 | }
59 |
60 | return !(_fail || (main_time>=start_time+duration));
61 | }
62 |
63 | ////////////////////////////TestCrc////////////////////////////
64 |
65 | TestCrc::TestCrc()
66 | {
67 | }
68 |
69 | void TestCrc::start()
70 | {
71 | printf("TestCrc started");
72 | top->clear = 0;
73 | top->enable = 0;
74 |
75 | currentSeed = 0;
76 | currentBit = 0;
77 | }
78 |
79 | void TestCrc::beforeEval()
80 | {
81 | if(clockRising())
82 | return;
83 |
84 | started = true;
85 | top->enable = 1;
86 | top->crc = currentSeed;
87 | top->in = currentBit;
88 | }
89 |
90 | bool TestCrc::afterEval()
91 | {
92 | if(_fail)
93 | return false;
94 |
95 | if(clockFalling())
96 | return true;
97 |
98 | if(!started)
99 | return true;
100 |
101 | uint16_t expectedValue = crc16_1bit(currentSeed, currentBit);
102 | if(top->crc != expectedValue)
103 | {
104 | printf("TestClear crc not equal %x!=%x\n", (uint32_t)top->crc, (uint32_t)expectedValue);
105 | printf(" seed=%x, data_in=%x", (uint32_t)currentSeed, (uint32_t)currentBit);
106 |
107 | _fail = true;
108 | return false;
109 | }
110 |
111 | currentBit++;
112 | if(currentBit==2)
113 | {
114 | if((currentSeed&0xFF)==0)
115 | printf("\n seed=%x", (uint32_t)currentSeed);
116 | currentBit = 0;
117 | if(currentSeed==0xFFFF)
118 | return false;
119 | currentSeed++;
120 | }
121 |
122 | return true;
123 | }
124 |
125 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_crc16/tests.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Vsd_crc16.h"
4 | #include
5 | #include
6 | #include "crc16.h"
7 |
8 | class VerilogTest
9 | {
10 | public:
11 | VerilogTest();
12 | virtual ~VerilogTest();
13 |
14 | virtual void init(Vsd_crc16* top);
15 | virtual void start()=0;
16 | virtual void beforeEval()=0;
17 | //return false if test completed
18 | virtual bool afterEval()=0;
19 | virtual bool fail() { return _fail; }
20 | protected:
21 | Vsd_crc16* top = nullptr;
22 | bool _fail = false;
23 | };
24 |
25 | class TestClear : public VerilogTest
26 | {
27 | public:
28 | TestClear(vluint64_t duration = 32);
29 | void start() override;
30 |
31 | void beforeEval() override;
32 | bool afterEval() override;
33 | protected:
34 | vluint64_t start_time;
35 | vluint64_t duration;
36 | };
37 |
38 |
39 | class TestCrc : public VerilogTest
40 | {
41 | public:
42 | TestCrc();
43 |
44 | void start() override;
45 | void beforeEval() override;
46 | bool afterEval() override;
47 |
48 | protected:
49 | bool started = false;
50 | uint16_t currentSeed;
51 | uint8_t currentBit;
52 | };
53 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/Makefile_obj:
--------------------------------------------------------------------------------
1 | CPPFLAGS += -MMD -MP
2 | CPPFLAGS += -g # defug info
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/makefile:
--------------------------------------------------------------------------------
1 | VERILATOR_FLAGS =
2 | # Generate C++ in executable form
3 | VERILATOR_FLAGS += -cc --exe
4 | # Generate makefile dependencies (not shown as complicates the Makefile)
5 | #VERILATOR_FLAGS += -MMD
6 | # Optimize
7 | #VERILATOR_FLAGS += -O2 -x-assign 0
8 | # Warn abount lint issues; may not want this on less solid designs
9 | VERILATOR_FLAGS += -Wall
10 | # Make waveforms
11 | VERILATOR_FLAGS += --trace
12 | # Check SystemVerilog assertions
13 | VERILATOR_FLAGS += --assert
14 | # Generate coverage analysis
15 | VERILATOR_FLAGS += --coverage
16 | # Run Verilator in debug mode
17 | #VERILATOR_FLAGS += --debug
18 | # Add this trace to get a backtrace in gdb
19 | VERILATOR_FLAGS += --gdbbt
20 |
21 |
22 | build:
23 | @mkdir -p logs
24 | verilator $(VERILATOR_FLAGS) --top-module sd_read_stream ../../sdio_project/code/sdio_slave/sd_read_stream.sv ../../sdio_project/code/sdio_slave/sd_crc7.sv sim_main.cpp tests.cpp
25 | $(MAKE) -j -C obj_dir -f Vsd_read_stream.mk Vsd_read_stream -f ../Makefile_obj
26 |
27 | run:
28 | obj_dir/Vsd_read_stream +trace
29 |
30 | clean:
31 | -rm -rf obj_dir logs
32 |
33 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/sd_read_stream.cflags:
--------------------------------------------------------------------------------
1 | -std=c17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/sd_read_stream.config:
--------------------------------------------------------------------------------
1 | // Add predefined macros for your project here. For example:
2 | // #define THE_ANSWER 42
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/sd_read_stream.creator:
--------------------------------------------------------------------------------
1 | [General]
2 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/sd_read_stream.cxxflags:
--------------------------------------------------------------------------------
1 | -std=c++17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/sd_read_stream.files:
--------------------------------------------------------------------------------
1 | tests.cpp
2 | tests.h
3 | obj_dir/Vspi_tx.cpp
4 | obj_dir/Vspi_tx.h
5 | obj_dir/Vspi_tx__ALLcls.cpp
6 | obj_dir/Vspi_tx__ALLsup.cpp
7 | obj_dir/Vspi_tx__Syms.cpp
8 | obj_dir/Vspi_tx__Syms.h
9 | obj_dir/Vspi_tx__Trace.cpp
10 | obj_dir/Vspi_tx__Trace__Slow.cpp
11 | sim_main.cpp
12 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/sd_read_stream.includes:
--------------------------------------------------------------------------------
1 | obj_dir
2 | .
3 | /home/balmer/radio/altera/soft/verilator/verilator/include
4 |
5 | /usr/include
6 | /usr/include/c++/7
7 | /usr/include/x86_64-linux-gnu
8 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/sim_main.cpp:
--------------------------------------------------------------------------------
1 | #include "verilated.h"
2 | #include
3 |
4 | #include "tests.h"
5 | #include
6 |
7 | // Current simulation time (64-bit unsigned)
8 | vluint64_t main_time = 0;
9 | // Called by $time in Verilog
10 | double sc_time_stamp() {
11 | return main_time; // Note does conversion to real, to match SystemC
12 | }
13 |
14 | int main(int argc, char** argv, char** env)
15 | {
16 | Verilated::commandArgs(argc, argv);
17 | Vsd_read_stream* top = new Vsd_read_stream;
18 | // If verilator was invoked with --trace argument,
19 | // and if at run time passed the +trace argument, turn on tracing
20 | VerilatedVcdC* tfp = NULL;
21 | const char* flag = Verilated::commandArgsPlusMatch("trace");
22 | if (flag && 0==strcmp(flag, "+trace")) {
23 | Verilated::traceEverOn(true); // Verilator must compute traced signals
24 | VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
25 | tfp = new VerilatedVcdC;
26 | top->trace(tfp, 99); // Trace 99 levels of hierarchy
27 | Verilated::mkdir("logs");
28 | tfp->open("logs/vlt_dump.vcd"); // Open the dump file
29 | }
30 |
31 | top->clock = 0;
32 | top->sd_clock = 0;
33 | top->sd_serial = 1;
34 | top->read_enabled = 1;
35 |
36 | std::vector> test;
37 | test.push_back(std::make_shared(20));
38 | test.push_back(std::make_shared(1));
39 | test.push_back(std::make_shared(20));
40 | test.push_back(std::make_shared(0x3FFFFFFFFF));
41 |
42 | test.push_back(std::make_shared(0x3FFFFFFFFF, TestRead::Bad::CRC));
43 | test.push_back(std::make_shared(0x3FFFFFFFFF, TestRead::Bad::Direction));
44 | test.push_back(std::make_shared(0x3FFFFFFFFF, TestRead::Bad::EndBit));
45 | test.push_back(std::make_shared(20));
46 | test.push_back(std::make_shared(0x1FFF));
47 | test.push_back(std::make_shared(1, TestRead::Bad::ReadDisabled));
48 |
49 |
50 | int current_test = -1;
51 | bool next_test = true;
52 | bool test_failed = false;
53 |
54 | while (!Verilated::gotFinish())
55 | {
56 | if(next_test)
57 | {
58 | current_test++;
59 | if(current_test>=test.size())
60 | break;
61 | next_test = false;
62 | test[current_test]->init(top);
63 | test[current_test]->start();
64 | }
65 |
66 | top->clock = (main_time&1)?1:0;
67 | top->sd_clock = ((main_time/4)&1)?1:0;
68 | test[current_test]->beforeEval();
69 |
70 | top->eval();
71 | // Dump trace data for this cycle
72 | if (tfp) tfp->dump (main_time);
73 |
74 | if(!test[current_test]->afterEval())
75 | {
76 | if(test[current_test]->fail())
77 | {
78 | printf("---- Failed\n");
79 | test_failed = true;
80 | break;
81 | }
82 |
83 | printf("---- Succeeded\n");
84 | next_test = true;
85 | }
86 |
87 |
88 | main_time++; // Time passes...
89 | }
90 |
91 | if(test_failed)
92 | printf("Tests failed\n");
93 | else
94 | printf("All tests succeeded\n");
95 |
96 |
97 | // Final model cleanup
98 | top->final();
99 |
100 | // Close trace if opened
101 | if (tfp) { tfp->close(); tfp = NULL; }
102 |
103 | delete top;
104 | exit(test_failed?1:0);
105 | }
106 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/tests.cpp:
--------------------------------------------------------------------------------
1 | #include "tests.h"
2 |
3 | #include "../sd_response_stream/crc7.h"
4 |
5 | //Global time counter
6 | //Время идет по пол такта.
7 | //Тоесть за один такт main_time изменяется на 2
8 | //Несетные - clock = 1, четные clock = 0
9 | extern vluint64_t main_time;
10 | bool clockRising() { return (main_time&1)==1; }
11 | bool clockFalling() { return (main_time&1)==0; }
12 | //bool clockSck() { return (main_time/2)%32==1; }
13 | //bool clockSck() { return (main_time/2)%4==1; }
14 | bool clockSck() { return (main_time/2)%2==1; }
15 |
16 | VerilogTest::VerilogTest()
17 | {
18 | }
19 |
20 | VerilogTest::~VerilogTest()
21 | {
22 | }
23 |
24 | void VerilogTest::init(Vsd_read_stream *top)
25 | {
26 | this->top = top;
27 | }
28 |
29 | TestSilence::TestSilence(vluint64_t duration)
30 | : duration(duration)
31 | {
32 |
33 | }
34 |
35 |
36 | void TestSilence::start()
37 | {
38 | start_time = main_time;
39 | printf("TestSilence started");
40 | top->sd_serial = 1;
41 | }
42 |
43 | void TestSilence::beforeEval()
44 | {
45 |
46 | }
47 |
48 | bool TestSilence::afterEval()
49 | {
50 |
51 | if(top->data_strobe!=0)
52 | {
53 | printf("TestSilence fail sd_serial\n");
54 | _fail = true;
55 | }
56 |
57 | if(top->read_error!=0)
58 | {
59 | printf("TestSilence fail write_enabled\n");
60 | _fail = true;
61 | }
62 |
63 | return !(_fail || (main_time>=start_time+duration));
64 | }
65 |
66 | ////////////////////////////TestRead////////////////////////////
67 | TestRead::TestRead(uint64_t data38, Bad bad)
68 | : data38(data38)
69 | , bad(bad)
70 | {
71 | dataToSend = make_sd_command(data38, bad==Bad::Direction?false:true);
72 |
73 | if(bad==Bad::CRC)
74 | dataToSend = dataToSend&~0x8Eull;
75 | if(bad==Bad::EndBit)
76 | dataToSend = dataToSend&~(1ull);
77 | }
78 |
79 | void TestRead::start()
80 | {
81 | top->sd_serial = 1;
82 | prev_sd_clock = top->sd_clock;
83 | currentBit = 48;
84 | minTicks = 40;
85 |
86 | top->read_enabled = (bad==Bad::ReadDisabled)?0:1;
87 | }
88 |
89 | void TestRead::beforeEval()
90 | {
91 | if(clockFalling())
92 | return;
93 |
94 | if(prev_sd_clock==1 && top->sd_clock==0)
95 | {
96 | if(currentBit>0)
97 | currentBit--;
98 | top->sd_serial = (dataToSend>>currentBit)&1;
99 | }
100 |
101 | prev_sd_clock = top->sd_clock;
102 |
103 | }
104 |
105 | bool TestRead::afterEval()
106 | {
107 | if(_fail)
108 | return false;
109 |
110 | if(!clockRising())
111 | return true;
112 |
113 | if(top->data_strobe)
114 | {
115 | if(top->read_error)
116 | {
117 | printf("TestRead data_strobe==1 && read_error==1");
118 | _fail = true;
119 | return false;
120 | }
121 |
122 | data_ok = top->data==data38;
123 | if(!data_ok)
124 | {
125 | printf("TestRead top->data!=data38");
126 | _fail = true;
127 | return false;
128 | }
129 | }
130 |
131 | if(top->read_error)
132 | {
133 | if(bad==Bad::None)
134 | {
135 | printf("TestRead read error");
136 | _fail = true;
137 | return false;
138 | } else {
139 | error_ok = true;
140 | }
141 | }
142 |
143 | if(currentBit==0)
144 | minTicks--;
145 |
146 |
147 | if(minTicks==0)
148 | {
149 | if(bad==Bad::None)
150 | {
151 | if(!data_ok)
152 | {
153 | printf("TestRead data not received");
154 | _fail = true;
155 | return false;
156 | }
157 | } else
158 | {
159 | if(bad==Bad::ReadDisabled)
160 | {
161 | if(error_ok || data_ok)
162 | {
163 | printf("TestRead ReadDisabled, but data received!");
164 | _fail = true;
165 | return false;
166 | }
167 |
168 | } else
169 | {
170 | if(!error_ok)
171 | {
172 | printf("TestRead error not received");
173 | _fail = true;
174 | return false;
175 | }
176 | }
177 | }
178 | }
179 |
180 | return minTicks>0;
181 | }
182 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream/tests.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Vsd_read_stream.h"
4 | #include
5 | #include
6 |
7 | class VerilogTest
8 | {
9 | public:
10 | VerilogTest();
11 | virtual ~VerilogTest();
12 |
13 | virtual void init(Vsd_read_stream* top);
14 | virtual void start()=0;
15 | virtual void beforeEval()=0;
16 | //return false if test completed
17 | virtual bool afterEval()=0;
18 | virtual bool fail() { return _fail; }
19 | protected:
20 | Vsd_read_stream* top = nullptr;
21 | bool _fail = false;
22 | };
23 |
24 | //Простейшая проверка. Если ничего не посылаем,
25 | //то SPI никаких сигналов не производит.
26 | class TestSilence : public VerilogTest
27 | {
28 | public:
29 | TestSilence(vluint64_t duration = 32);
30 | void start() override;
31 |
32 | void beforeEval() override;
33 | bool afterEval() override;
34 | protected:
35 | vluint64_t start_time;
36 | vluint64_t duration;
37 | };
38 |
39 |
40 | class TestRead : public VerilogTest
41 | {
42 | public:
43 | enum class Bad
44 | {
45 | None,
46 | CRC,
47 | Direction,
48 | EndBit,
49 | ReadDisabled,
50 | };
51 |
52 | //data - 38 бит произвольных данных
53 | TestRead(uint64_t data38, Bad bad = Bad::None);
54 |
55 | void start() override;
56 | void beforeEval() override;
57 | bool afterEval() override;
58 |
59 | protected:
60 | uint64_t data38;
61 | uint64_t dataToSend;
62 |
63 | int currentBit;
64 | int minTicks;
65 | uint8_t prev_sd_clock;
66 |
67 | bool data_ok = false;
68 | bool error_ok = false;
69 | Bad bad;
70 | };
71 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/Makefile_obj:
--------------------------------------------------------------------------------
1 | CPPFLAGS += -MMD -MP
2 | CPPFLAGS += -g # defug info
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/makefile:
--------------------------------------------------------------------------------
1 | VERILATOR_FLAGS =
2 | # Generate C++ in executable form
3 | VERILATOR_FLAGS += -cc --exe
4 | # Generate makefile dependencies (not shown as complicates the Makefile)
5 | #VERILATOR_FLAGS += -MMD
6 | # Optimize
7 | #VERILATOR_FLAGS += -O2 -x-assign 0
8 | # Warn abount lint issues; may not want this on less solid designs
9 | VERILATOR_FLAGS += -Wall
10 | # Make waveforms
11 | VERILATOR_FLAGS += --trace
12 | # Check SystemVerilog assertions
13 | VERILATOR_FLAGS += --assert
14 | # Generate coverage analysis
15 | VERILATOR_FLAGS += --coverage
16 | # Run Verilator in debug mode
17 | #VERILATOR_FLAGS += --debug
18 | # Add this trace to get a backtrace in gdb
19 | VERILATOR_FLAGS += --gdbbt
20 |
21 | SV_DIR = ../../sdio_project/code/sdio_slave
22 |
23 | build:
24 | @mkdir -p logs
25 | verilator $(VERILATOR_FLAGS) --top-module sd_read_stream_dat $(SV_DIR)/sd_typedef.sv $(SV_DIR)/sd_read_stream_dat.sv $(SV_DIR)/sd_crc16.sv sim_main.cpp tests.cpp
26 | $(MAKE) -j -C obj_dir -f Vsd_read_stream_dat.mk Vsd_read_stream_dat -f ../Makefile_obj
27 |
28 | run:
29 | obj_dir/Vsd_read_stream_dat +trace
30 |
31 | clean:
32 | -rm -rf obj_dir logs
33 |
34 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/sd_read_stream_dat.cflags:
--------------------------------------------------------------------------------
1 | -std=c17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/sd_read_stream_dat.config:
--------------------------------------------------------------------------------
1 | // Add predefined macros for your project here. For example:
2 | // #define THE_ANSWER 42
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/sd_read_stream_dat.creator:
--------------------------------------------------------------------------------
1 | [General]
2 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/sd_read_stream_dat.cxxflags:
--------------------------------------------------------------------------------
1 | -std=c++17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/sd_read_stream_dat.files:
--------------------------------------------------------------------------------
1 | tests.cpp
2 | tests.h
3 | obj_dir/Vspi_tx.cpp
4 | obj_dir/Vspi_tx.h
5 | obj_dir/Vspi_tx__ALLcls.cpp
6 | obj_dir/Vspi_tx__ALLsup.cpp
7 | obj_dir/Vspi_tx__Syms.cpp
8 | obj_dir/Vspi_tx__Syms.h
9 | obj_dir/Vspi_tx__Trace.cpp
10 | obj_dir/Vspi_tx__Trace__Slow.cpp
11 | sim_main.cpp
12 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/sd_read_stream_dat.includes:
--------------------------------------------------------------------------------
1 | obj_dir
2 | .
3 | /home/balmer/radio/altera/soft/verilator/verilator/include
4 |
5 | /usr/include
6 | /usr/include/c++/7
7 | /usr/include/x86_64-linux-gnu
8 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/sim_main.cpp:
--------------------------------------------------------------------------------
1 | #include "verilated.h"
2 | #include
3 |
4 | #include "tests.h"
5 | #include
6 |
7 | // Current simulation time (64-bit unsigned)
8 | vluint64_t main_time = 0;
9 | // Called by $time in Verilog
10 | double sc_time_stamp() {
11 | return main_time; // Note does conversion to real, to match SystemC
12 | }
13 |
14 | int main(int argc, char** argv, char** env)
15 | {
16 | Verilated::commandArgs(argc, argv);
17 | Vsd_read_stream_dat* top = new Vsd_read_stream_dat;
18 | // If verilator was invoked with --trace argument,
19 | // and if at run time passed the +trace argument, turn on tracing
20 | VerilatedVcdC* tfp = NULL;
21 | const char* flag = Verilated::commandArgsPlusMatch("trace");
22 | if (flag && 0==strcmp(flag, "+trace")) {
23 | Verilated::traceEverOn(true); // Verilator must compute traced signals
24 | VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
25 | tfp = new VerilatedVcdC;
26 | top->trace(tfp, 99); // Trace 99 levels of hierarchy
27 | Verilated::mkdir("logs");
28 | tfp->open("logs/vlt_dump.vcd"); // Open the dump file
29 | }
30 |
31 | top->clock = 0;
32 | top->sd_clock = 0;
33 | top->sd_data = 0xF;
34 | top->read_strobe = 0;
35 | top->data_count = 0;
36 |
37 | std::vector> test;
38 | test.push_back(std::make_shared(20));
39 |
40 | std::vector data;
41 |
42 | data.push_back(0xFE);
43 | test.push_back(std::make_shared(data));
44 |
45 | data.clear();
46 | data.push_back(0x10);
47 | data.push_back(0x13);
48 | test.push_back(std::make_shared(data));
49 |
50 | data.clear();
51 | data.push_back(0x40);
52 | data.push_back(0x41);
53 | data.push_back(0x42);
54 | data.push_back(0x43);
55 | test.push_back(std::make_shared(data));
56 |
57 | data = std::vector {0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1 };
58 | test.push_back(std::make_shared(data));
59 |
60 | int current_test = -1;
61 | bool next_test = true;
62 | bool test_failed = false;
63 |
64 | while (!Verilated::gotFinish())
65 | {
66 | if(next_test)
67 | {
68 | current_test++;
69 | if(current_test>=test.size())
70 | break;
71 | next_test = false;
72 | test[current_test]->init(top);
73 | test[current_test]->start();
74 | }
75 |
76 | top->clock = (main_time&1)?1:0;
77 | top->sd_clock = ((main_time/4)&1)?1:0;
78 | test[current_test]->beforeEval();
79 |
80 | top->eval();
81 | // Dump trace data for this cycle
82 | if (tfp) tfp->dump (main_time);
83 |
84 | if(!test[current_test]->afterEval())
85 | {
86 | if(test[current_test]->fail())
87 | {
88 | printf("---- Failed\n");
89 | test_failed = true;
90 | break;
91 | }
92 |
93 | printf("---- Succeeded\n");
94 | next_test = true;
95 | }
96 |
97 |
98 | main_time++; // Time passes...
99 | }
100 |
101 | if(test_failed)
102 | printf("Tests failed\n");
103 | else
104 | printf("All tests succeeded\n");
105 |
106 |
107 | // Final model cleanup
108 | top->final();
109 |
110 | // Close trace if opened
111 | if (tfp) { tfp->close(); tfp = NULL; }
112 |
113 | delete top;
114 | exit(test_failed?1:0);
115 | }
116 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/tests.cpp:
--------------------------------------------------------------------------------
1 | #include "tests.h"
2 | #include "../sd_crc16/crc16.h"
3 |
4 | //Global time counter
5 | //Время идет по пол такта.
6 | //Тоесть за один такт main_time изменяется на 2
7 | //Несетные - clock = 1, четные clock = 0
8 | extern vluint64_t main_time;
9 | bool clockRising() { return (main_time&1)==1; }
10 | bool clockFalling() { return (main_time&1)==0; }
11 | bool clockSck() { return (main_time/2)%2==1; }
12 |
13 | VerilogTest::VerilogTest()
14 | {
15 | }
16 |
17 | VerilogTest::~VerilogTest()
18 | {
19 | }
20 |
21 | void VerilogTest::init(Vsd_read_stream_dat *top)
22 | {
23 | this->top = top;
24 | }
25 |
26 | TestSilence::TestSilence(vluint64_t duration)
27 | : duration(duration)
28 | {
29 |
30 | }
31 |
32 |
33 | void TestSilence::start()
34 | {
35 | start_time = main_time;
36 | printf("TestSilence started\n");
37 | }
38 |
39 | void TestSilence::beforeEval()
40 | {
41 |
42 | }
43 |
44 | bool TestSilence::afterEval()
45 | {
46 |
47 | if(top->sd_data!=0xF)
48 | {
49 | printf("TestSilence fail sd_serial\n");
50 | _fail = true;
51 | }
52 |
53 | if(top->write_byte_strobe!=0)
54 | {
55 | printf("TestSilence fail write_byte_strobe\n");
56 | _fail = true;
57 | }
58 |
59 | if(top->write_all_strobe!=0)
60 | {
61 | printf("TestSilence fail write_all_strobe\n");
62 | _fail = true;
63 | }
64 |
65 | return !(_fail || (main_time>=start_time+duration));
66 | }
67 |
68 | ////////////////////////////TestRead////////////////////////////
69 |
70 | TestRead::TestRead(std::vector data)
71 | : data(data)
72 | {
73 | for(size_t i=0; i>4;
79 | for(size_t i=0; i>i)&1);
81 |
82 | nibble = d&0xF;
83 |
84 | for(size_t i=0; i>i)&1);
86 | }
87 | }
88 |
89 | void TestRead::start()
90 | {
91 | printf("TestRead started bytes=%i\n", (int)data.size());
92 | //for(size_t i=0; iread_strobe = 1;
95 | top->sd_data = 0xF;
96 | top->data_count = data.size();
97 |
98 | prev_sd_clock = top->sd_clock;
99 | }
100 |
101 | void TestRead::beforeEval()
102 | {
103 | if(clockFalling())
104 | return;
105 |
106 | if(prev_sd_clock==0 && top->sd_clock==1)
107 | {
108 | switch(state)
109 | {
110 | case State::Starting:
111 | {
112 | top->sd_data = 0xF;
113 | state = State::WriteZero;
114 | break;
115 | }
116 | case State::WriteZero:
117 | {
118 | top->sd_data = 0;
119 | state = State::WriteData;
120 | break;
121 | }
122 | case State::WriteData:
123 | {
124 | uint8_t d = data[currentIndexX2/2];
125 | if(currentIndexX2&1)
126 | top->sd_data = d&0xF;
127 | else
128 | top->sd_data = (d>>4)&0xF;
129 | currentIndexX2++;
130 |
131 | if(currentIndexX2/2==data.size())
132 | state = State::WriteCRC;
133 | break;
134 | }
135 | case State::WriteCRC:
136 | {
137 | int offset = 15-crcWriteIdx;
138 |
139 | uint8_t p = 0;
140 | for(int i=0; i<4; i++)
141 | {
142 | uint8_t d = (crcCalculated[i]>>offset)&1;
143 | //uint8_t d = (crcCalculated[0]>>offset)&1;
144 | p |= (d<sd_data = p;
148 |
149 | crcWriteIdx++;
150 | if(crcWriteIdx==16)
151 | state = State::WriteOne;
152 | break;
153 | }
154 | case State::WriteOne:
155 | {
156 | top->sd_data = 0xF;
157 | state = State::Complete;
158 | break;
159 | }
160 | case State::Complete:
161 | {
162 | break;
163 | }
164 | }
165 | }
166 |
167 | }
168 |
169 | bool TestRead::afterEval()
170 | {
171 | if(_fail)
172 | return false;
173 |
174 | if(!clockRising())
175 | return true;
176 |
177 | top->read_strobe = 0;
178 | prev_sd_clock = top->sd_clock;
179 |
180 | if(top->write_byte_strobe)
181 | {
182 | dataReceived.push_back(top->byte_out);
183 | if(dataReceived.size()>data.size())
184 | {
185 | printf("TestRead too many data size=%i\n", (int)dataReceived.size());
186 | _fail = true;
187 | return false;
188 | } else
189 | {
190 | size_t idx = dataReceived.size()-1;
191 | if(dataReceived[idx]!=data[idx])
192 | {
193 | printf("TestRead idx=%i received=%x original=%x\n", (int)idx, (int)dataReceived[idx], (int)data[idx]);
194 | _fail = true;
195 | return false;
196 | }
197 |
198 | }
199 | }
200 |
201 | if(top->write_all_strobe)
202 | {
203 | writeAllFound = true;
204 | if(dataReceived.size()!=data.size())
205 | {
206 | printf("TestRead complete not equal size received=%i original=%i\n", (int)dataReceived.size(), (int)data.size());
207 | _fail = true;
208 | return false;
209 | }
210 |
211 | if(top->crc_ok!=1)
212 | {
213 | printf("TestRead bad CRC\n");
214 | _fail = true;
215 | }
216 | }
217 |
218 | if(state==State::Complete)
219 | {
220 | if(waitAterWrite==0)
221 | {
222 | if(!writeAllFound)
223 | {
224 | printf("TestRead writeAllFound==false\n");
225 | _fail = true;
226 | }
227 |
228 | return false;
229 | }
230 |
231 | waitAterWrite--;
232 | }
233 |
234 | return true;
235 | }
236 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_read_stream_dat/tests.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Vsd_read_stream_dat.h"
4 | #include
5 | #include
6 | #include
7 |
8 | class VerilogTest
9 | {
10 | public:
11 | VerilogTest();
12 | virtual ~VerilogTest();
13 |
14 | virtual void init(Vsd_read_stream_dat* top);
15 | virtual void start()=0;
16 | virtual void beforeEval()=0;
17 | //return false if test completed
18 | virtual bool afterEval()=0;
19 | virtual bool fail() { return _fail; }
20 | protected:
21 | Vsd_read_stream_dat* top = nullptr;
22 | bool _fail = false;
23 | };
24 |
25 | //Простейшая проверка. Если ничего не посылаем,
26 | //то SPI никаких сигналов не производит.
27 | class TestSilence : public VerilogTest
28 | {
29 | public:
30 | TestSilence(vluint64_t duration = 32);
31 | void start() override;
32 |
33 | void beforeEval() override;
34 | bool afterEval() override;
35 | protected:
36 | vluint64_t start_time;
37 | vluint64_t duration;
38 | };
39 |
40 |
41 | class TestRead : public VerilogTest
42 | {
43 | public:
44 | //data - 38 бит произвольных данных
45 | TestRead(std::vector data);
46 |
47 | void start() override;
48 | void beforeEval() override;
49 | bool afterEval() override;
50 |
51 | protected:
52 | enum class State
53 | {
54 | Starting,
55 | WriteZero,
56 | WriteData,
57 | WriteCRC,
58 | WriteOne,
59 | Complete
60 | };
61 |
62 | std::vector data;
63 | std::vector dataReceived;
64 | size_t currentIndexX2 = 0;
65 |
66 | std::array crcCalculated;
67 | int crcWriteIdx = 0;
68 |
69 | State state = State::Starting;
70 |
71 | uint8_t prev_sd_clock;
72 | bool writeAllFound = false;
73 |
74 | int waitAterWrite = 3;
75 | };
76 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/Makefile_obj:
--------------------------------------------------------------------------------
1 | CPPFLAGS += -MMD -MP
2 | CPPFLAGS += -g # defug info
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/crc7.h:
--------------------------------------------------------------------------------
1 | inline uint8_t crc7(uint8_t prev, bool bit)
2 | {
3 | /*
4 | Расчет crc7 побитно
5 | prev - предыдущее значение (изначально равно 0).
6 | bit - новый бит добавленный в последовательность.
7 | возвращает новое crc7 значение вместе с этим битом.
8 | */
9 |
10 | uint8_t inv = (bit?1:0) ^ ((prev>>6)&1);
11 |
12 | return (((prev<<1)|inv)^(inv<<3))&0b1111111;
13 | }
14 |
15 | //40 байт из 48-ми битного слова
16 | inline uint8_t crc7_of_command(uint64_t data)
17 | {
18 | uint8_t crc7_data = 0;
19 | for(int i=47; i>7; i--)
20 | crc7_data = crc7(crc7_data, (data>>i)&1);
21 |
22 | return crc7_data;
23 | }
24 |
25 | /*
26 | * data38 - 38 бит полезных данных
27 | */
28 | inline uint64_t make_sd_command(uint64_t data38, bool host_to_periphery)
29 | {
30 | uint64_t out = 0;
31 | if(host_to_periphery)
32 | out |= (1ull<<46);
33 |
34 | out |= (data38<<8);
35 | out |= crc7_of_command(out)<<1;
36 | //Последний бит всегда 1
37 | out |= 1;
38 |
39 | return out;
40 | }
41 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/makefile:
--------------------------------------------------------------------------------
1 | VERILATOR_FLAGS =
2 | # Generate C++ in executable form
3 | VERILATOR_FLAGS += -cc --exe
4 | # Generate makefile dependencies (not shown as complicates the Makefile)
5 | #VERILATOR_FLAGS += -MMD
6 | # Optimize
7 | #VERILATOR_FLAGS += -O2 -x-assign 0
8 | # Warn abount lint issues; may not want this on less solid designs
9 | VERILATOR_FLAGS += -Wall
10 | # Make waveforms
11 | VERILATOR_FLAGS += --trace
12 | # Check SystemVerilog assertions
13 | VERILATOR_FLAGS += --assert
14 | # Generate coverage analysis
15 | VERILATOR_FLAGS += --coverage
16 | # Run Verilator in debug mode
17 | #VERILATOR_FLAGS += --debug
18 | # Add this trace to get a backtrace in gdb
19 | VERILATOR_FLAGS += --gdbbt
20 |
21 |
22 | build:
23 | @mkdir -p logs
24 | verilator $(VERILATOR_FLAGS) --top-module sd_response_stream ../../sdio_project/code/sdio_slave/sd_response_stream.sv ../../sdio_project/code/sdio_slave/sd_crc7.sv sim_main.cpp tests.cpp
25 | $(MAKE) -j -C obj_dir -f Vsd_response_stream.mk Vsd_response_stream -f ../Makefile_obj
26 |
27 | run:
28 | obj_dir/Vsd_response_stream +trace
29 |
30 | clean:
31 | -rm -rf obj_dir logs
32 |
33 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/sd_response_stream.cflags:
--------------------------------------------------------------------------------
1 | -std=c17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/sd_response_stream.config:
--------------------------------------------------------------------------------
1 | // Add predefined macros for your project here. For example:
2 | // #define THE_ANSWER 42
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/sd_response_stream.creator:
--------------------------------------------------------------------------------
1 | [General]
2 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/sd_response_stream.cxxflags:
--------------------------------------------------------------------------------
1 | -std=c++17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/sd_response_stream.files:
--------------------------------------------------------------------------------
1 | tests.cpp
2 | tests.h
3 | obj_dir/Vspi_tx.cpp
4 | obj_dir/Vspi_tx.h
5 | obj_dir/Vspi_tx__ALLcls.cpp
6 | obj_dir/Vspi_tx__ALLsup.cpp
7 | obj_dir/Vspi_tx__Syms.cpp
8 | obj_dir/Vspi_tx__Syms.h
9 | obj_dir/Vspi_tx__Trace.cpp
10 | obj_dir/Vspi_tx__Trace__Slow.cpp
11 | sim_main.cpp
12 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/sd_response_stream.includes:
--------------------------------------------------------------------------------
1 | obj_dir
2 | .
3 | /home/balmer/radio/altera/soft/verilator/verilator/include
4 |
5 | /usr/include
6 | /usr/include/c++/7
7 | /usr/include/x86_64-linux-gnu
8 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/sim_main.cpp:
--------------------------------------------------------------------------------
1 | #include "verilated.h"
2 | #include
3 |
4 | #include "tests.h"
5 | #include
6 |
7 | // Current simulation time (64-bit unsigned)
8 | vluint64_t main_time = 0;
9 | // Called by $time in Verilog
10 | double sc_time_stamp() {
11 | return main_time; // Note does conversion to real, to match SystemC
12 | }
13 |
14 | int main(int argc, char** argv, char** env)
15 | {
16 | Verilated::commandArgs(argc, argv);
17 | Vsd_response_stream* top = new Vsd_response_stream;
18 | // If verilator was invoked with --trace argument,
19 | // and if at run time passed the +trace argument, turn on tracing
20 | VerilatedVcdC* tfp = NULL;
21 | const char* flag = Verilated::commandArgsPlusMatch("trace");
22 | if (flag && 0==strcmp(flag, "+trace")) {
23 | Verilated::traceEverOn(true); // Verilator must compute traced signals
24 | VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
25 | tfp = new VerilatedVcdC;
26 | top->trace(tfp, 99); // Trace 99 levels of hierarchy
27 | Verilated::mkdir("logs");
28 | tfp->open("logs/vlt_dump.vcd"); // Open the dump file
29 | }
30 |
31 | top->clock = 0;
32 | top->data = 0;
33 | top->data_strobe = 0;
34 | top->sd_clock = 0;
35 |
36 | std::vector> test;
37 | test.push_back(std::make_shared(20));
38 | test.push_back(std::make_shared(1));
39 | test.push_back(std::make_shared(1));
40 | test.push_back(std::make_shared(0x123456));
41 |
42 | int current_test = -1;
43 | bool next_test = true;
44 | bool test_failed = false;
45 |
46 | while (!Verilated::gotFinish())
47 | {
48 | if(next_test)
49 | {
50 | current_test++;
51 | if(current_test>=test.size())
52 | break;
53 | next_test = false;
54 | test[current_test]->init(top);
55 | test[current_test]->start();
56 | }
57 |
58 | top->clock = (main_time&1)?1:0;
59 | top->sd_clock = ((main_time/4)&1)?1:0;
60 | test[current_test]->beforeEval();
61 |
62 | top->eval();
63 | // Dump trace data for this cycle
64 | if (tfp) tfp->dump (main_time);
65 |
66 | if(!test[current_test]->afterEval())
67 | {
68 | if(test[current_test]->fail())
69 | {
70 | printf("---- Failed\n");
71 | test_failed = true;
72 | break;
73 | }
74 |
75 | printf("---- Succeeded\n");
76 | next_test = true;
77 | }
78 |
79 |
80 | main_time++; // Time passes...
81 | }
82 |
83 | if(test_failed)
84 | printf("Tests failed\n");
85 | else
86 | printf("All tests succeeded\n");
87 |
88 |
89 | // Final model cleanup
90 | top->final();
91 |
92 | // Close trace if opened
93 | if (tfp) { tfp->close(); tfp = NULL; }
94 |
95 | delete top;
96 | exit(test_failed?1:0);
97 | }
98 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/tests.cpp:
--------------------------------------------------------------------------------
1 | #include "tests.h"
2 | #include "crc7.h"
3 |
4 | //Global time counter
5 | //Время идет по пол такта.
6 | //Тоесть за один такт main_time изменяется на 2
7 | //Несетные - clock = 1, четные clock = 0
8 | extern vluint64_t main_time;
9 | bool clockRising() { return (main_time&1)==1; }
10 | bool clockFalling() { return (main_time&1)==0; }
11 | //bool clockSck() { return (main_time/2)%32==1; }
12 | //bool clockSck() { return (main_time/2)%4==1; }
13 | bool clockSck() { return (main_time/2)%2==1; }
14 |
15 | VerilogTest::VerilogTest()
16 | {
17 | }
18 |
19 | VerilogTest::~VerilogTest()
20 | {
21 | }
22 |
23 | void VerilogTest::init(Vsd_response_stream *top)
24 | {
25 | this->top = top;
26 | }
27 |
28 | TestSilence::TestSilence(vluint64_t duration)
29 | : duration(duration)
30 | {
31 |
32 | }
33 |
34 |
35 | void TestSilence::start()
36 | {
37 | start_time = main_time;
38 | printf("TestSilence started\n");
39 | }
40 |
41 | void TestSilence::beforeEval()
42 | {
43 |
44 | }
45 |
46 | bool TestSilence::afterEval()
47 | {
48 |
49 | if(top->sd_serial!=1)
50 | {
51 | printf("TestSilence fail sd_serial\n");
52 | _fail = true;
53 | }
54 |
55 | if(top->write_enabled!=0)
56 | {
57 | printf("TestSilence fail write_enabled\n");
58 | _fail = true;
59 | }
60 |
61 | return !(_fail || (main_time>=start_time+duration));
62 | }
63 |
64 | ////////////////////////////TestWrite////////////////////////////
65 |
66 | TestWrite::TestWrite(uint64_t data38)
67 | : data38(data38)
68 | {
69 |
70 | dataOriginal = make_sd_command(data38, false);
71 | dataReceived = 0;
72 | }
73 |
74 | void TestWrite::start()
75 | {
76 | top->data = data38;
77 |
78 | prev_sd_clock = top->sd_clock;
79 | }
80 |
81 | void TestWrite::beforeEval()
82 | {
83 | if(clockFalling())
84 | return;
85 |
86 | if(strobe_time==0)
87 | top->data_strobe = 1;
88 | else
89 | top->data_strobe = 0;
90 |
91 | strobe_time++;
92 |
93 | }
94 |
95 | bool TestWrite::afterEval()
96 | {
97 | if(_fail)
98 | return false;
99 |
100 | if(!clockRising())
101 | return true;
102 |
103 | if(prev_sd_clock==1 && top->sd_clock==0)
104 | {
105 | if(top->write_enabled)
106 | {
107 | bool is_pre_bit = bits_received==0 && top->sd_serial==1;
108 | bool is_post_bit = bits_received==48 && top->sd_serial==1;
109 | if(!is_pre_bit && !is_post_bit)
110 | {
111 | dataReceived = (dataReceived<<1)|top->sd_serial;
112 | bits_received++;
113 | }
114 | }
115 | }
116 |
117 | prev_sd_clock = top->sd_clock;
118 |
119 | minTicks--;
120 |
121 | if(minTicks==0)
122 | {
123 | if(top->write_enabled)
124 | {
125 | printf("Error: top->write_enabled==1 long time\n");
126 | _fail = true;
127 | }
128 |
129 | if(bits_received!=48)
130 | {
131 | printf("Error: bits_received!=48 bits_received=%i\n", bits_received);
132 | _fail = true;
133 | }
134 |
135 | if(dataOriginal!=dataReceived)
136 | {
137 | printf("dataOriginal!=dataReceived\n");
138 | printf(" original=0x%lx\n", dataOriginal);
139 | printf(" received=0x%lx\n", dataReceived);
140 | _fail = true;
141 | }
142 | }
143 |
144 | return minTicks>0;
145 | }
146 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream/tests.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Vsd_response_stream.h"
4 | #include
5 | #include
6 |
7 | class VerilogTest
8 | {
9 | public:
10 | VerilogTest();
11 | virtual ~VerilogTest();
12 |
13 | virtual void init(Vsd_response_stream* top);
14 | virtual void start()=0;
15 | virtual void beforeEval()=0;
16 | //return false if test completed
17 | virtual bool afterEval()=0;
18 | virtual bool fail() { return _fail; }
19 | protected:
20 | Vsd_response_stream* top = nullptr;
21 | bool _fail = false;
22 | };
23 |
24 | //Простейшая проверка. Если ничего не посылаем,
25 | //то SPI никаких сигналов не производит.
26 | class TestSilence : public VerilogTest
27 | {
28 | public:
29 | TestSilence(vluint64_t duration = 32);
30 | void start() override;
31 |
32 | void beforeEval() override;
33 | bool afterEval() override;
34 | protected:
35 | vluint64_t start_time;
36 | vluint64_t duration;
37 | };
38 |
39 |
40 | class TestWrite : public VerilogTest
41 | {
42 | public:
43 | //data - 38 бит произвольных данных
44 | TestWrite(uint64_t data38);
45 |
46 | void start() override;
47 | void beforeEval() override;
48 | bool afterEval() override;
49 |
50 | protected:
51 | uint64_t data38;
52 | uint64_t dataOriginal;
53 | uint64_t dataReceived;
54 |
55 | int minTicks = 240;
56 | uint8_t prev_sd_clock;
57 | uint8_t strobe_time = 0;
58 | int bits_received = 0;
59 | };
60 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/Makefile_obj:
--------------------------------------------------------------------------------
1 | CPPFLAGS += -MMD -MP
2 | CPPFLAGS += -g # defug info
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/makefile:
--------------------------------------------------------------------------------
1 | VERILATOR_FLAGS =
2 | # Generate C++ in executable form
3 | VERILATOR_FLAGS += -cc --exe
4 | # Generate makefile dependencies (not shown as complicates the Makefile)
5 | #VERILATOR_FLAGS += -MMD
6 | # Optimize
7 | #VERILATOR_FLAGS += -O2 -x-assign 0
8 | # Warn abount lint issues; may not want this on less solid designs
9 | VERILATOR_FLAGS += -Wall
10 | # Make waveforms
11 | VERILATOR_FLAGS += --trace
12 | # Check SystemVerilog assertions
13 | VERILATOR_FLAGS += --assert
14 | # Generate coverage analysis
15 | VERILATOR_FLAGS += --coverage
16 | # Run Verilator in debug mode
17 | #VERILATOR_FLAGS += --debug
18 | # Add this trace to get a backtrace in gdb
19 | VERILATOR_FLAGS += --gdbbt
20 |
21 |
22 | build:
23 | @mkdir -p logs
24 | verilator $(VERILATOR_FLAGS) --top-module sd_response_stream_dat ../../sdio_project/code/sdio_slave/sd_response_stream_dat.sv ../../sdio_project/code/sdio_slave/sd_crc16.sv sim_main.cpp tests.cpp
25 | $(MAKE) -j -C obj_dir -f Vsd_response_stream_dat.mk Vsd_response_stream_dat -f ../Makefile_obj
26 |
27 | run:
28 | obj_dir/Vsd_response_stream_dat +trace
29 |
30 | clean:
31 | -rm -rf obj_dir logs
32 |
33 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/sd_response_stream_dat.cflags:
--------------------------------------------------------------------------------
1 | -std=c17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/sd_response_stream_dat.config:
--------------------------------------------------------------------------------
1 | // Add predefined macros for your project here. For example:
2 | // #define THE_ANSWER 42
3 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/sd_response_stream_dat.creator:
--------------------------------------------------------------------------------
1 | [General]
2 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/sd_response_stream_dat.cxxflags:
--------------------------------------------------------------------------------
1 | -std=c++17
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/sd_response_stream_dat.files:
--------------------------------------------------------------------------------
1 | tests.cpp
2 | tests.h
3 | obj_dir/Vspi_tx.cpp
4 | obj_dir/Vspi_tx.h
5 | obj_dir/Vspi_tx__ALLcls.cpp
6 | obj_dir/Vspi_tx__ALLsup.cpp
7 | obj_dir/Vspi_tx__Syms.cpp
8 | obj_dir/Vspi_tx__Syms.h
9 | obj_dir/Vspi_tx__Trace.cpp
10 | obj_dir/Vspi_tx__Trace__Slow.cpp
11 | sim_main.cpp
12 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/sd_response_stream_dat.includes:
--------------------------------------------------------------------------------
1 | obj_dir
2 | .
3 | /home/balmer/radio/altera/soft/verilator/verilator/include
4 |
5 | /usr/include
6 | /usr/include/c++/7
7 | /usr/include/x86_64-linux-gnu
8 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/sim_main.cpp:
--------------------------------------------------------------------------------
1 | #include "verilated.h"
2 | #include
3 |
4 | #include "tests.h"
5 | #include
6 |
7 | // Current simulation time (64-bit unsigned)
8 | vluint64_t main_time = 0;
9 | // Called by $time in Verilog
10 | double sc_time_stamp() {
11 | return main_time; // Note does conversion to real, to match SystemC
12 | }
13 |
14 | int main(int argc, char** argv, char** env)
15 | {
16 | Verilated::commandArgs(argc, argv);
17 | Vsd_response_stream_dat* top = new Vsd_response_stream_dat;
18 | // If verilator was invoked with --trace argument,
19 | // and if at run time passed the +trace argument, turn on tracing
20 | VerilatedVcdC* tfp = NULL;
21 | const char* flag = Verilated::commandArgsPlusMatch("trace");
22 | if (flag && 0==strcmp(flag, "+trace")) {
23 | Verilated::traceEverOn(true); // Verilator must compute traced signals
24 | VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
25 | tfp = new VerilatedVcdC;
26 | top->trace(tfp, 99); // Trace 99 levels of hierarchy
27 | Verilated::mkdir("logs");
28 | tfp->open("logs/vlt_dump.vcd"); // Open the dump file
29 | }
30 |
31 | top->clock = 0;
32 | top->data = 0;
33 | top->data_strobe = 0;
34 | top->sd_clock = 0;
35 |
36 | std::vector> test;
37 | test.push_back(std::make_shared(20));
38 |
39 | test.push_back(std::make_shared(true));
40 | test.push_back(std::make_shared(false));
41 |
42 | std::vector data;
43 |
44 |
45 | data.push_back(0xFE);
46 | test.push_back(std::make_shared(data));
47 |
48 | data.clear();
49 | data.push_back(0x10);
50 | data.push_back(0x13);
51 | test.push_back(std::make_shared(data));
52 |
53 | data.clear();
54 | data.push_back(0x40);
55 | data.push_back(0x41);
56 | data.push_back(0x42);
57 | data.push_back(0x43);
58 | test.push_back(std::make_shared(data));
59 |
60 | data = std::vector {0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1 };
61 | test.push_back(std::make_shared(data));
62 |
63 | test.push_back(std::make_shared(true));
64 | test.push_back(std::make_shared(false));
65 |
66 |
67 | int current_test = -1;
68 | bool next_test = true;
69 | bool test_failed = false;
70 |
71 | while (!Verilated::gotFinish())
72 | {
73 | if(next_test)
74 | {
75 | current_test++;
76 | if(current_test>=test.size())
77 | break;
78 | next_test = false;
79 | test[current_test]->init(top);
80 | test[current_test]->start();
81 | }
82 |
83 | top->clock = (main_time&1)?1:0;
84 | top->sd_clock = ((main_time/4)&1)?1:0;
85 | test[current_test]->beforeEval();
86 |
87 | top->eval();
88 | // Dump trace data for this cycle
89 | if (tfp) tfp->dump (main_time);
90 |
91 | if(!test[current_test]->afterEval())
92 | {
93 | if(test[current_test]->fail())
94 | {
95 | printf("---- Failed\n");
96 | test_failed = true;
97 | break;
98 | }
99 |
100 | printf("---- Succeeded\n");
101 | next_test = true;
102 | }
103 |
104 |
105 | main_time++; // Time passes...
106 | }
107 |
108 | if(test_failed)
109 | printf("Tests failed\n");
110 | else
111 | printf("All tests succeeded\n");
112 |
113 |
114 | // Final model cleanup
115 | top->final();
116 |
117 | // Close trace if opened
118 | if (tfp) { tfp->close(); tfp = NULL; }
119 |
120 | delete top;
121 | exit(test_failed?1:0);
122 | }
123 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/tests.cpp:
--------------------------------------------------------------------------------
1 | #include "tests.h"
2 | #include "../sd_crc16/crc16.h"
3 |
4 | //Global time counter
5 | //Время идет по пол такта.
6 | //Тоесть за один такт main_time изменяется на 2
7 | //Несетные - clock = 1, четные clock = 0
8 | extern vluint64_t main_time;
9 | bool clockRising() { return (main_time&1)==1; }
10 | bool clockFalling() { return (main_time&1)==0; }
11 | bool clockSck() { return (main_time/2)%2==1; }
12 |
13 | VerilogTest::VerilogTest()
14 | {
15 | }
16 |
17 | VerilogTest::~VerilogTest()
18 | {
19 | }
20 |
21 | void VerilogTest::init(Vsd_response_stream_dat *top)
22 | {
23 | this->top = top;
24 | }
25 |
26 | TestSilence::TestSilence(vluint64_t duration)
27 | : duration(duration)
28 | {
29 |
30 | }
31 |
32 |
33 | void TestSilence::start()
34 | {
35 | start_time = main_time;
36 | printf("TestSilence started\n");
37 | }
38 |
39 | void TestSilence::beforeEval()
40 | {
41 |
42 | }
43 |
44 | bool TestSilence::afterEval()
45 | {
46 |
47 | if(top->sd_data!=0xF)
48 | {
49 | printf("TestSilence fail sd_serial\n");
50 | _fail = true;
51 | }
52 |
53 | if(top->write_enabled!=0)
54 | {
55 | printf("TestSilence fail write_enabled\n");
56 | _fail = true;
57 | }
58 |
59 | return !(_fail || (main_time>=start_time+duration));
60 | }
61 |
62 | ////////////////////////////TestWrite////////////////////////////
63 |
64 | TestWrite::TestWrite(std::vector data)
65 | : data(data)
66 | {
67 | for(size_t i=0; i>4;
76 | for(size_t i=0; i>i)&1);
78 |
79 | nibble = d&0xF;
80 |
81 | for(size_t i=0; i>i)&1);
83 | }
84 | }
85 |
86 | void TestWrite::start()
87 | {
88 | top->start_write = 1;
89 | top->data_empty = 0;
90 | top->data_strobe = 0;
91 |
92 | prev_sd_clock = top->sd_clock;
93 | }
94 |
95 | void TestWrite::beforeEval()
96 | {
97 | if(clockFalling())
98 | return;
99 | }
100 |
101 | bool TestWrite::afterEval()
102 | {
103 | if(_fail)
104 | return false;
105 |
106 | if(!clockRising())
107 | return true;
108 |
109 | top->start_write = 0;
110 | top->data_strobe = 0;
111 |
112 | if(top->data_req)
113 | {
114 | if(currentIndex < data.size())
115 | {
116 | top->data =data[currentIndex];
117 | top->data_strobe = 1;
118 | currentIndex++;
119 | } else {
120 | top->data_empty = 1;
121 | }
122 | }
123 |
124 |
125 | if(prev_sd_clock==1 && top->sd_clock==0)
126 | {
127 | if(top->write_enabled)
128 | {
129 | writeEnabledFound = true;
130 | bool is_pre_bit = halfReceived==0 && top->sd_data==0xF;
131 | if(!is_pre_bit)
132 | {
133 | if(halfReceived==0 && top->sd_data!=0)
134 | {
135 | printf("Error: start top->sd_data!=0\n");
136 | _fail = true;
137 | return false;
138 | }
139 |
140 | if(halfReceived>0)
141 | {
142 | size_t curByte = (halfReceived-1)/2;
143 | bool isTopHalf = (halfReceived&1)?true:false;
144 | if(isTopHalf)
145 | {
146 | curReceived = top->sd_data<<4;
147 |
148 | if(crcReceivedIdx==8)
149 | {
150 | if(top->sd_data!=0xF)
151 | {
152 | printf("Error: end top->sd_data!=0xF\n");
153 | _fail = true;
154 | return false;
155 | }
156 | }
157 | } else
158 | {
159 | uint8_t d = curReceived | top->sd_data;
160 |
161 | if(dataReceived.size() < data.size())
162 | {
163 | dataReceived.push_back(d);
164 | printf("Info: byte idx=%i received=%x original=%x\n", (int)curByte, dataReceived[curByte], data[curByte]);
165 | if(data[curByte]!=dataReceived[curByte])
166 | {
167 | printf("Error: byte not equal idx=%i received=%x original=%x\n", (int)curByte, dataReceived[curByte], data[curByte]);
168 | _fail = true;
169 | return false;
170 | }
171 | } else
172 | {
173 | if(crcReceivedIdx<8)
174 | {
175 | uint16_t d16 = d;
176 | for(size_t i=0; i>(4+i))&1)<>i)&1)<<(offset-1);
181 | }
182 |
183 | crcReceivedIdx++;
184 | }
185 | }
186 |
187 | }
188 | }
189 |
190 |
191 | halfReceived++;
192 | }
193 | } else
194 | {
195 | if(writeEnabledFound)
196 | {
197 | if(waitAterWrite==0)
198 | {
199 | for(size_t i=0; i16)
214 | return false;
215 | }
216 | }
217 | }
218 |
219 | prev_sd_clock = top->sd_clock;
220 |
221 | return true;
222 | }
223 |
224 | ////////////////////////////TestCrcStatus////////////////////////////
225 |
226 | TestCrcStatus::TestCrcStatus(bool positive)
227 | : positive(positive)
228 | {
229 | data = positive ? 0b00101 : 0b01011;
230 | dataReceived = 0;
231 | }
232 |
233 | void TestCrcStatus::start()
234 | {
235 | printf("TestCrcStatus started ");
236 | top->start_send_crc_status = 1;
237 | top->crc_status = positive?1:0;
238 | prev_sd_clock = top->sd_clock;
239 | }
240 |
241 | void TestCrcStatus::beforeEval()
242 | {
243 | if(clockFalling())
244 | return;
245 | }
246 |
247 | bool TestCrcStatus::afterEval()
248 | {
249 | if(_fail)
250 | return false;
251 |
252 | if(!clockRising())
253 | return true;
254 |
255 | top->start_send_crc_status = 0;
256 |
257 | if(prev_sd_clock==1 && top->sd_clock==0)
258 | {
259 | if(top->write_enabled)
260 | {
261 | writeEnabledFound = true;
262 | bool is_pre_bit = dataReceivedIdx==0 && top->sd_data==0xF;
263 | if(!is_pre_bit)
264 | {
265 | if(dataReceivedIdx==0 && (top->sd_data&1)!=0)
266 | {
267 | printf("Error: start top->sd_data!=0\n");
268 | _fail = true;
269 | return false;
270 | }
271 |
272 | if(dataReceivedIdx < bitsCount)
273 | {
274 | dataReceived = (dataReceived<<1) | (top->sd_data&1);
275 | dataReceivedIdx++;
276 | } else
277 | {
278 | if(top->sd_data!=0xF)
279 | {
280 | printf("Error: start top->sd_data!=0xF\n");
281 | _fail = true;
282 | return false;
283 | }
284 | }
285 | }
286 | } else
287 | {
288 | if(writeEnabledFound)
289 | {
290 | if(waitAterWrite==0)
291 | {
292 | if(dataReceivedIdx!=bitsCount)
293 | {
294 | printf("Error: bits received %i\n", dataReceivedIdx);
295 | _fail = true;
296 | return false;
297 | }
298 |
299 | if(data!=dataReceived)
300 | {
301 | printf("Error: received=%x calculated=%x\n", (uint32_t)dataReceived, (uint32_t)data);
302 | _fail = true;
303 | return false;
304 | }
305 | }
306 |
307 | waitAterWrite++;
308 |
309 | if(waitAterWrite>16)
310 | return false;
311 | }
312 | }
313 | }
314 |
315 | prev_sd_clock = top->sd_clock;
316 |
317 | return true;
318 | }
319 |
--------------------------------------------------------------------------------
/fpga/verilator_tests/sd_response_stream_dat/tests.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Vsd_response_stream_dat.h"
4 | #include
5 | #include
6 | #include
7 |
8 | class VerilogTest
9 | {
10 | public:
11 | VerilogTest();
12 | virtual ~VerilogTest();
13 |
14 | virtual void init(Vsd_response_stream_dat* top);
15 | virtual void start()=0;
16 | virtual void beforeEval()=0;
17 | //return false if test completed
18 | virtual bool afterEval()=0;
19 | virtual bool fail() { return _fail; }
20 | protected:
21 | Vsd_response_stream_dat* top = nullptr;
22 | bool _fail = false;
23 | };
24 |
25 | //Простейшая проверка. Если ничего не посылаем,
26 | //то SPI никаких сигналов не производит.
27 | class TestSilence : public VerilogTest
28 | {
29 | public:
30 | TestSilence(vluint64_t duration = 32);
31 | void start() override;
32 |
33 | void beforeEval() override;
34 | bool afterEval() override;
35 | protected:
36 | vluint64_t start_time;
37 | vluint64_t duration;
38 | };
39 |
40 |
41 | class TestWrite : public VerilogTest
42 | {
43 | public:
44 | //data - 38 бит произвольных данных
45 | TestWrite(std::vector data);
46 |
47 | void start() override;
48 | void beforeEval() override;
49 | bool afterEval() override;
50 |
51 | protected:
52 | std::vector data;
53 | std::vector dataReceived;
54 | size_t currentIndex = 0;
55 |
56 | std::array crcCalculated;
57 | std::array crcReceived;
58 | int crcReceivedIdx = 0;
59 |
60 | uint8_t prev_sd_clock;
61 | int halfReceived = 0;
62 | uint8_t curReceived = 0;
63 | bool writeEnabledFound = false;
64 |
65 | int waitAterWrite = 0;
66 | };
67 |
68 |
69 | class TestCrcStatus : public VerilogTest
70 | {
71 | public:
72 | TestCrcStatus(bool positive);
73 |
74 | void start() override;
75 | void beforeEval() override;
76 | bool afterEval() override;
77 |
78 | protected:
79 | const int bitsCount = 5;
80 | bool positive;
81 | uint8_t data;
82 | uint8_t dataReceived;
83 | size_t currentIndex = 0;
84 |
85 | int dataReceivedIdx = 0;
86 |
87 | uint8_t prev_sd_clock;
88 | bool writeEnabledFound = false;
89 |
90 | int waitAterWrite = 0;
91 | };
92 |
--------------------------------------------------------------------------------
/img/overview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balmerdx/sdio_linux_fpga/e77e89ad648ecdbf16aefb1ca826b12053787748/img/overview.jpg
--------------------------------------------------------------------------------
/info.txt:
--------------------------------------------------------------------------------
1 | Всякие мелочи, которые я пишу по мере продвижения проекта.
2 |
3 | В папке /home/balmer/radio/pi/buildroot/buildroot-licheepi-zero-licheepi-zero
4 | Пишем образ на SD карту
5 | sudo dd if=output/images/sdcard.img of=/dev/sdb bs=4M oflag=dsync
6 | sync
7 |
8 |
9 | Терминал Linux через UART
10 | cu -l /dev/ttyUSB0 -s 115200
11 |
12 | Компиляция Linux полная
13 | make BR2_EXTERNAL=/home/balmer/radio/pi/buildroot/my_buildroot BR2_TARGET_UBOOT_BOARD_DEFCONFIG=LicheePi_Zero_800x480LCD
14 | BR2_TARGET_UBOOT_BOARD_DEFCONFIG = /home/balmer/radio/pi/buildroot/my_buildroot/boot/configs/LicheePi_Zero_800x480LCD_defconfig
15 |
16 | Перекомпиляция нашего драйвера
17 | make balmer_sdio_uart-rebuild BR2_EXTERNAL=/home/balmer/radio/pi/buildroot/my_buildroot BR2_TARGET_UBOOT_BOARD_DEFCONFIG=LicheePi_Zero_800x480LCD
18 |
19 | Местоположение драйвера на SD карте
20 | /lib/modules/4.14.14-licheepi-zero/extra/balmer_sdio_uart.ko
21 | чтобы загрузить - надо перейти в эту директорию и написать
22 | wget http://192.168.1.38:8000/balmer_sdio_uart.ko
23 | modprobe balmer_sdio_uart.ko
24 | Выгрузить модуль
25 | modprobe -r balmer_sdio_uart.ko
26 |
27 | Либо (из любой директории)
28 | insmod /lib/modules/4.14.14-licheepi-zero/extra/balmer_sdio_uart.ko
29 |
30 |
--------------------------------------------------------------------------------
/linux/balmer_sdio_uart/Config.in:
--------------------------------------------------------------------------------
1 | config BR2_PACKAGE_BALMER_SDIO_UART
2 | bool "balmer_sdio_uart"
3 | depends on BR2_LINUX_KERNEL
4 | help
5 | See README.adoc
6 |
--------------------------------------------------------------------------------
/linux/balmer_sdio_uart/Makefile:
--------------------------------------------------------------------------------
1 | obj-m += $(addsuffix .o, $(notdir $(basename $(filter-out %.mod.c, $(wildcard $(BR2_EXTERNAL_LPI_PATH)/balmer_sdio_uart/*.c)))))
2 | ccflags-y := -DDEBUG -g -std=gnu99 -Werror -Wno-declaration-after-statement -Wframe-larger-than=1000000000
3 |
4 | .PHONY: all clean
5 |
6 | all:
7 | $(MAKE) -C '/lib/modules/$(shell uname -r)/build' M='$(PWD)' modules
8 |
9 | clean:
10 | $(MAKE) -C '$(LINUX_DIR)' M='$(PWD)' clean
11 |
--------------------------------------------------------------------------------
/linux/balmer_sdio_uart/README.adoc:
--------------------------------------------------------------------------------
1 | UART over SDIO balmer version
2 |
--------------------------------------------------------------------------------
/linux/balmer_sdio_uart/external.desc:
--------------------------------------------------------------------------------
1 | name: BALMER_SDIO_UART
2 |
--------------------------------------------------------------------------------
/linux/balmer_sdio_uart/external.mk:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | #
3 | # balmer_sdio_uart
4 | #
5 | ################################################################################
6 |
7 | BALMER_SDIO_UART_VERSION = 1.0
8 | BALMER_SDIO_UART_SITE = $(BR2_EXTERNAL_LPI_PATH)/balmer_sdio_uart
9 | BALMER_SDIO_UART_SITE_METHOD = local
10 |
11 | $(eval $(kernel-module))
12 | $(eval $(generic-package))
13 |
--------------------------------------------------------------------------------
/linux/sdio_test/Makefile:
--------------------------------------------------------------------------------
1 | CC=arm-linux-gnueabihf-gcc -Wall -pedantic -std=gnu11 -O3
2 | #CC=gcc -Wall -pedantic -std=c11 -O3
3 |
4 | read: sdio_read.c
5 | ${CC} $< -o $@
6 |
7 |
8 | write: sdio_write.c
9 | ${CC} $< -o $@
10 |
--------------------------------------------------------------------------------
/linux/sdio_test/http_server.sh:
--------------------------------------------------------------------------------
1 | python3 -m http.server 8000 --bind 0.0.0.0
2 |
--------------------------------------------------------------------------------
/linux/sdio_test/sdio_read.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "time_utils.h"
8 |
9 | const char* device_name = "/dev/balmerSDIO0";
10 |
11 | int main(void)
12 | {
13 | int fd;/*File Descriptor*/
14 |
15 | printf("SDIO Port Read\n");
16 |
17 | fd = open(device_name,O_RDWR);
18 | if(fd == -1)
19 | printf(" Error! in Opening %s\n", device_name);
20 | else
21 | printf(" %s Opened Successfully\n", device_name);
22 |
23 |
24 |
25 | static uint8_t read_buffer[4096];
26 | int bytes_read = 0;
27 | int i = 0;
28 |
29 | //msleep(100);
30 | uint64_t start_usec = TimeUsec();
31 | bytes_read = read(fd, read_buffer, sizeof(read_buffer));
32 | uint64_t end_usec = TimeUsec();
33 | printf(" Delta tume %i usec\n", (int)(end_usec-start_usec));
34 | printf(" Bytes received %d\n", bytes_read);
35 |
36 | //for(i=0;i
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | const char* device_name = "/dev/balmerSDIO0";
8 |
9 | #include "time_utils.h"
10 |
11 | int main(void)
12 | {
13 | int fd;
14 |
15 | printf("SDIO Port Write\n");
16 |
17 | fd = open(device_name,O_RDWR);
18 | if(fd == -1) /* Error Checking */
19 | printf(" Error! in Opening %s \n", device_name);
20 | else
21 | printf(" %s Opened Successfully \n", device_name);
22 |
23 | static char write_buffer[4096];
24 | int bytes_write = 0;
25 | int i = 0;
26 | for(i=0;i>8;
30 | else
31 | write_buffer[i] = i;
32 | }
33 |
34 | //msleep(100);
35 |
36 | uint64_t start_usec = TimeUsec();
37 | bytes_write = write(fd, write_buffer, sizeof(write_buffer));
38 | uint64_t end_usec = TimeUsec();
39 | printf("Delta tume %i usec\n", (int)(end_usec-start_usec));
40 | printf("Bytes write=%d\n", bytes_write);
41 | close(fd);
42 |
43 | return 0;
44 | }
45 |
46 |
47 |
--------------------------------------------------------------------------------
/linux/sdio_test/time_utils.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | static inline int msleep(long msec)
5 | {
6 | struct timespec ts;
7 | int res;
8 |
9 | if (msec < 0)
10 | {
11 | errno = EINVAL;
12 | return -1;
13 | }
14 |
15 | ts.tv_sec = msec / 1000;
16 | ts.tv_nsec = (msec % 1000) * 1000000;
17 |
18 | do {
19 | res = nanosleep(&ts, &ts);
20 | } while (res && errno == EINTR);
21 |
22 | return res;
23 | }
24 |
25 | static inline uint64_t TimeUsec()
26 | {
27 | struct timespec ts;
28 | timespec_get(&ts, TIME_UTC);
29 | return ts.tv_sec*(uint64_t)1000000+ts.tv_nsec/1000;
30 | }
31 |
--------------------------------------------------------------------------------