├── .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 | ![Общий вид](https://raw.githubusercontent.com/balmerdx/sdio_linux_fpga/master/img/overview.jpg) 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 | --------------------------------------------------------------------------------