Государственное образовательное учреждение высшего профессионального образования «Московский государственный технический университет имени Н.Э. Баумана» (МГТУ им. Н.Э. Баумана) ФАКУЛЬТЕТ «ИНФОРМАТИКИ И СИСТЕМ УПРАВЛЕНИЯ» КАФЕДРА ИУ4 «ПРОЕКТИРОВАНИЕ И ТЕХНОЛОГИЯ ПРОИЗВОДСТВА ЭА» Домашнее задание№4 на тему: Кардридер. Изучение интерфейса SPI. по курсу: Системотехника ЭВС. Комплексы и сети. Студенты: Нестеров В.А., Белоус Е.С. Рейтинговая оценка: Проверил: Шпиев В.А. (Подпись, дата) (И.О.Фамилия) (Подпись, дата) (И.О.Фамилия) Консультант: Москва 2012 1 Аннотация Домашнее задание посвящено изучению контроллера интерфейса SPI. В ходе работы проведён структурный анализ блоков SPI-master и SPI-slave. Рассмотрена структура блоков, управляющих и информационных сигналов. На основе структурных диаграмм, разработанных ранее, блоки SPI-master и SPI-slave описаны на языке Verilog и проведено моделирование разработанных блоков. Abstract Homework is devoted to the study of the interface controller SPI. The work carried out structural analysis of blocks SPI-master and SPI-slave. The structure of the blocks, control and information signals. On the basis of structural diagrams, developed earlier, blocks SPI master and the SPI-slave described in the language of Verilog and simulated designed block. 2 Содержание Введение…………………………………………………………………………………….. 4 1 Счётчик. ……………………………………………………………………………………. 4 1.1 Реализация проекта при помощи графического редактора схем …………… 4 1.2 Схемотехническое описание схемы………………………………………………. 4 1.3 Моделирование собранной схемы………………………………………………… 5 2 КонтроллерSPI…..………………………………………………………………………… 9 2.1 Система управления картой памяти………...………………………………… 9 2.2 Реализация блока SPI-master на языке HDL…………………………………… 12 2.3 Моделирование блока SPI-master…………………………………..……………. 16 2.4 Синтез блока SPI-master…………………………………………………………… 19 Заключение………………………………………………………………………………….. 21 3 1 Счётчик 1.1 Реализация проекта при помощи графического редактора схем. На семинаре была реализована схема счётчика, который инкрементируется по нажатию кнопки (контакт “Button”), значение с которого после дешифрации попадёт на семисегментный индикатор. Для простоты возьмем диапазон цифр от 0 до 3, т.к. дело осложняется тем, что в среде нет семисегментного дешифратора и его придется сделать вручную. На рисунке 1.1.1 показана схема счётчика, собранная в графическом редакторе САПР ISE WEB PACK (version 13.3). Рисунок 1.1.1 – Схема счётчика в графической среде САПР Далее будет проведено моделирование схемы инструментами САПР ISE WEB PACK и получение временных диаграмм. 1.2 Схемотехническое описание собранной схемы. Схема работает следующим образом. Сигнал с кнопки представляет собой довольно продолжительный сигнал относительно тактовой частоты, поэтому, чтобы по каждому нажатию осуществлялся переход счетчика только на одно значение вперед, применена схема преобразования фронта в импульс, состоящая из D-триггера (на рисунке – FD) и элемента «И» с одним инвертированным входом. Сигнал с кнопки задерживается триггером на один такт и инвертируется, после чего логически умножается на исходный сигнал. Другие два D-триггера служат для защиты синхронизации сигнала и защиты от метастабильности. 4 Полученный короткий импульс поступает на разрешающий сигнал двухразрядного двоичного счетчика (на рисунке – CB2CE). Выходы счетчика дешифрируются в значения сегментов семисегментного индикатора простыми логическими элементами (на рисунке находятся справа, расположены в столбиком). Сигнал сброса счетчика подключен к земле, т.к. счетчик сбрасывается автоматически, когда достигает значения больше 3. Сигнал переполнения счетчика (TC) и выходной сигнал разрешения работы счетчика для каскадирования (CEO) не используются. Схема имеет два входных вывода, Clock и Button, и 7 выходных, по количеству сегментов индикатора – Segment_A, Segment_B, Segment_C, Segment_D, Segment_E, Segment_F и Segment_G. 1.3 Моделирование собранной схемы. Для моделирования собранной схемы нужно создать так называемый испытательный стенд, или TestBench, суть которого в том, что он будет подавать на блок, который мы создали путём использования графического редактора или кода VHDL, определенные сигналы, позволяющие проверить его работу посредством анализа получающихся временных диаграмм. Итак, вызываем пункт меню New Source…, в появившемся диалоговом окне указываем параметры, как на рисунке 1.3.1. Рисунок 1.3.1 – Окно добавления тестового файла Нажимаем кнопку Next, в следующем диалоговом окне будет предложено выбрать файл, к которому следует прикрепить наш испытательный стенд. Выбираем файл main_vhdl и нажимаем Next. В следующем диалоговом окне содержится краткая информация о создаваемом файле, убедившись в правильности которой нажимаем кнопку Finish. В результате получаем файл main_scheme_tb.vhd, с исходным кодом, который представлен в листинге 1.3.1. 5 Листинг 1.3.1. -- Vhdl test bench created from schematic C:\Xilinx\Xilinx_project\Proj2\main_scheme.sch - Mon May 07 23:30:01 2012 -- Notes: -- 1) This testbench template has been automatically generated using types -- std_logic and std_logic_vector for the ports of the unit under test. -- Xilinx recommends that these types always be used for the top -level -- I/O of a design in order to guarantee that the testbench will bind -- correctly to the timing (post-route) simulation model. -- 2) To use this template as your testbench , change the filename to any -- name of your choice with the extension .vhd, and use the "Source ->Add" -- menu in Project Navigator to import the testbench. Then -- edit the user defined section below, adding code to generate the -- stimulus for your design. LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; LIBRARY UNISIM; USE UNISIM.Vcomponents.ALL; ENTITY main_scheme_main_scheme_sch_tb IS END main_scheme_main_scheme_sch_tb; ARCHITECTURE behavioral OF main_scheme_main_scheme_sch_tb IS COMPONENT main_scheme PORT( Button : Reset : IN CE : OUT CLK : IN Segment_A : Segment_C : Segment_D : Segment_E : Segment_F : Segment_G : Segment_B : test : OUT END COMPONENT; SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL SIGNAL Button Reset CE : CLK : Segment_A Segment_C Segment_D Segment_E Segment_F Segment_G Segment_B test : IN STD_LOGIC; STD_LOGIC; STD_LOGIC; STD_LOGIC; OUT STD_LOGIC; OUT STD_LOGIC; OUT STD_LOGIC; OUT STD_LOGIC; OUT STD_LOGIC; OUT STD_LOGIC; OUT STD_LOGIC; STD_LOGIC); : STD_LOGIC; : STD_LOGIC; STD_LOGIC; STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; : STD_LOGIC; STD_LOGIC; BEGIN UUT: main_scheme PORT MAP( Button => Button, Reset => Reset, CE => CE, CLK => CLK, Segment_A => Segment_A, Segment_C => Segment_C, Segment_D => Segment_D, Segment_E => Segment_E, Segment_F => Segment_F, Segment_G => Segment_G, Segment_B => Segment_B, test => test ); 6 -- *** Test Bench - User Defined Section *** tb : PROCESS BEGIN WAIT; -- will wait forever END PROCESS; -- *** End Test Bench - User Defined Section *** END; Дописываем код в соответствии с листингом 3.4.2. Листинг 1.3.2. <предыдущую часть оставляем без изменений> BEGIN -- Instantiate the Unit Under Test (UUT) uut: main_scheme PORT MAP( CLK => CLK, Button => Button, Segment_A => Segment_A, Segment_B => Segment_B, Segment_C => Segment_C, Segment_D => Segment_D, Segment_E => Segment_E, Segment_F => Segment_F, Segment_G => Segment_G, test => test, Reset => Reset, CE => CE ); CLK <= not CLK after 10 ns; tb : PROCESS BEGIN wait for 2 ns; Reset <='1'; wait for 5 ns; Reset<='0'; wait for 100 ns; Button <= '0'; wait for 500 ns; Button <= '1'; wait for 300 ns; Button <= '0'; wait for 700 ns; Button <= '1'; wait for 150 ns; Button <= '0'; wait for 400 ns; Button <= '1'; wait for 200 ns; Button <= '0'; wait for 600 ns; Button <= '1'; wait for 250 ns; wait; -- will wait forever END PROCESS; END; 7 Теперь в окне Simulations выбираем значение Behavorial. Выбираем наш файл main_scheme_tb в окне Hierarchy и в окне Procsesses дважды щелкаем по надписи Behavioral Check Syntax и после по Simulate Behavorial Model. В результате этих действий загрузится среда ISim. В результате моделирования получили временную диаграмму, как на рисунке 1.3.2, из которой ясно видно работу нашего проекта. Рисунок 1.3.2 – Временная диаграмма работы собранного счётчика Из временной диаграммы, полученной в результате моделирования схемы main_scheme можно видеть, что после сброса счётчика CB2CE на выходе устанавливается код 1111110, что соответствует цифре 0 на 7сегментом индикаторе. После при поступлении сигнала Button (т.е. при нажатии кнопки) значение счётчика инкрементируется и на выходе устанавливается значение 01100000, что соответствует цифре 1 на 7 сегментом индикаторе. При следующем нажатии устанавливается значение 1101101, что соответствует цифре 2 на 7-сегментом индикаторе. Таким образом, можно сделать вывод что схема работает корректно. 8 2 Контроллер SPI 2.1 Система управления картой памяти Карта памяти, как было разобрано выше, способна общаться с внешним миром по интерфейсу SPI. Считывающее устройство передаёт по интерфейсу SPIна карту памяти управляющие команды и записываемые данные. Контроллер SPI-интерфейса карты памяти преобразует принятые данные в параллельный код, обрабатываемый контроллером карты памяти. Также через интерфейс SPI с карты памяти передаются записанные на неё данные. Команды управления картой памятью формируются на стороне считывающего устройства. Внутри считывающего устройства формировани е команд происходит в процессоре и по общей шине передаётся в контроллер интерфейса SPI, где код преобразуется из параллельного в последовательный и передаётся карте памяти. Данные, принятые с карты памяти преобразуются обратно в параллельный код и записывается во внутреннюю память считывающего устройства. Затем из памяти эти данные передаются по интерфейса USB на компьютер. Совместная структура, отображающая принцип обмена между картой памяти и считывающим устройством отображена на рисунке 2.1.1 Рисунок 2.1.1 – Структурная схема контроллера кардридера и карты памяти Представленная на рисунке 9.1. структурная схема показывает взаимодействие сторонних блоков (процессора, ОЗУ) с контроллером интерфейса SPI. Для более подробного изучения контроллера SPI (master) была разработана функциональная схема контроллера SPI (master), которая показана на рисунке 2.1.2. Управляющие сигналы: Reset SCLK WR (сигнал разрешения передачи данных) RD (сигнал разрешения приема данных) addr (выбор режима работы) 9 Данные на контроллер интерфейса поступают по 8-разрядной шине данных. По шине адреса подается 4-разрядный код, по которому выбирается приёмник (до 12 slaveблоков). Рисунок 2.1.2 – Структурная схема контроллера SPI (master) Для передачи данных на шину данных выставляется информация, после подаётся сигнал разрешения передачи данных, и по тактовому сигналу CLK сдвиговый регистр выставляет данные на шину MOSI в виде последовательного кода. Сигнал CLK формируется при помощи тактового генератора из входного тактового си гнала SCLK. Для приёма данных подаётся сигнал разрешения приема данных, и по тактовому сигналу CLK сдвиговый регистр выставляет данные на шину данных в виде параллельного кода. Структурная схема контроллера SPI (slave) показана на рисунке 2.1.3. Сдвиговый регистр slave-контроллера тактируется внешним тактовым сигналом СLK от master-контроллера. Когда данный блок выбран (подан сигнал SS) по тактовому сигналу CLK сдвиговый регистр блока записывает данные с линии MOSI. 10 Рисунок 2.1.3 – Структурная схема контроллера SPI (slave) На основе спроектированных структурных схем будет разработан блок SPI_master на языке Verilog и промоделирован. 11 2.2 Реализация блока SPI-master на языке HDL. Блок SPI-masterбыл реализован на языке Verilog на основании структурной схемы, разработанной в 3-м домашнем задании. Листинг кода приведён в листинге 2.1.1. Листинг 2.2.1. `timescale 10ns/1ns module SPI_Master ( inout [7:0] data_bus, input pro_clk, input miso, input [1:0] addr, input CS, input WR, input RD, // 8-разрядная шина данных // Тактовый сигнал процессора // Сигнал MISO (Master in slave out) // Шина состояния // Разрешение работы // Инициализация приёма // Инициализация передачи output reg mosi, output reg sclk, output [7:0] ss ); // Сигнал MOSI (Master out slave in) // Тактовый сигнал обмена данными // 8-разрядная шина выбора ведомого (Slave select) //*Внутреннии регистры блока*// reg [7:0] shift_register; // Сдвиговый регистр reg [7:0] txdata; // Буфер передачи reg [7:0] rxdata; // Буфер приёма reg [7:0] data_out; // 8-разрядная шина данных reg [7:0] data_out_en; // Разрешение чтения данных reg [7:0] control, status; // Регистр состояния (Определение параметров ss, CPOL, CPHA, делителя частоты) // Регистр статуса (Пустой регистр, используется для обнуления других регистров) reg [7:0] clk_divide; reg [3:0] count; reg slave_cs; reg spi_word_send; reg WR_rd; // Счетчик делителя частоты // Счётчик длины передаваемого/принимаемого слова // Флаг выбора ведомого устройства // Флаг готовности передачи следующего байта //Сигнал разрешения единичной передачи //*Внутреннии линии блока*// wire wire wire wire wire [7:0] data_in = data_bus; spi_clk_gen; [2:0] divide_factor = control[2:0]; CPOL = control[3]; CPHA = control[4]; /* Сигналы выбора ведомого устройства (Slave select) */ assign ss[7] = ~( control[7] & control[6] & control[5] & (~slave_cs)); assign ss[6] = ~( control[7] & control[6] & ~control[5] & (~slave_cs)); assign ss[5] = ~( control[7] & ~control[6] & control[5] & (~slave_cs)); assign ss[4] = ~( control[7] & ~control[6] & ~control[5] & (~slave_cs)); assign ss[3] = ~(~control[7] & control[6] & control[5] & (~slave_cs)); assign ss[2] = ~(~control[7] & control[6] & ~control[5] & (~slave_cs)); 12 assign ss[1] = ~(~control[7] & ~control[6] & control[5] & (~slave_cs)); assign ss[0] = ~(~control[7] & ~control[6] & ~control[5] & (~slave_cs)); /* Генератор тактовой частоты передачи */ assign spi_clk_gen = clk_divide[divide_factor]; always @(posedge WR) begin WR_rd<=1; end /* Делитель тактовой частоты */ always @ (negedge pro_clk) //по заднему фронту тактового сигнала begin clk_divide = clk_divide + 1; end /* Чтение сигнала MISO и сдвиг */ always @ (posedge (sclk ^ (CPHA ^ CPOL)) or posedge spi_word_send) begin if (spi_word_send) begin shift_register[7:0] = txdata; end else begin shift_register = shift_register << 1; shift_register[0] <= miso; end end /* Формирование сигнала MOSI */ always @ (negedge (sclk ^ (CPHA ^ CPOL)) or posedge spi_word_send) begin if (spi_word_send) begin // mosi = txdata[7]; mosi = txdata[count]; end else begin mosi = shift_register[7]; end end /* Контроль битов прерывания и статуса*/ always @ (posedge slave_cs or posedge spi_word_send) begin if (spi_word_send) begin status[0] = 0; end else begin status = 8'h01; rxdata = shift_register; // Обновление буфера чтения end 13 end /* Контроль буфера передачи. Новый байт передается после обновления буфера передачи */ always @ (posedge pro_clk) //по переднему фронту тактового сигнала begin if ((spi_word_send) & (count < 8)) begin slave_cs <= 0; end else if ((count == 8) & ~(sclk ^ CPOL)|~(WR_rd)) begin slave_cs <= 1; WR_rd<=0; end else if (count == 9) count <= 0; end /* Новый байт высталяется после обновления буфера передачи */ always @ (posedge pro_clk) //по переднему фронту тактового сигнала begin if ((CS & WR_rd & addr[1] & ~addr[0])|(CS & RD & addr[1] & addr[0])) begin spi_word_send <=1; end else begin spi_word_send <=0; end end /* Генератор тактовой частоты, выдаваемой на линию SCLK */ always @ (posedge spi_clk_gen) begin if (~slave_cs) begin sclk = ~sclk; end else if (~CPOL) begin sclk = 0; end else begin sclk = 1; end end /* Контроль длины слова */ always @ (posedge sclk or posedge slave_cs) begin //if (slave_cs) if (~(spi_word_send)) begin count = 0; end 14 else begin count = count + 1; end end /* Определение режима работы */ always @ (posedge pro_clk) //по переднему фронту тактового сигнала begin if (CS) begin case (addr) 2'b00 : if (WR) control <= data_in; 2'b01 : if (RD) data_out <= status; // Пусто 2'b10 : if (WR) txdata <= data_in; 2'b11 : if (RD) data_out <= rxdata; endcase end end /* Контроль разрешения чтения данных */ always @ (RD or data_out) begin if (RD) data_out_en = data_out; else data_out_en = 8'bz; end assign data_bus = data_out_en; initial begin mosi = 0; control = 0; count = 0; slave_cs = 1; txdata = 0; rxdata = 0; clk_divide = 0; data_out = 0; end endmodule 15 2.3 Моделирование блока SPI-master на языке HDL. Блок SPI-master был реализован на языке Verilog. Для тестирования написанного блока используется TestBench-файл, содержащий входные воздействия. Файл TestBench написан на языке Verilog представлен в листинге 2.3.1. Листинг 2.3.1. //----------------------------------------------------------------------------// // Title : SPI_Master_tb // Design : SPI // Author : // Company : // //----------------------------------------------------------------------------// // File : SPI_Master_TB.v // Generated : Wed May 9 22:14:23 2012 // From : c:\My_Designs\SPI\SPI\src\TestBench\SPI_Master_TB_settings.txt // By : tb_verilog.pl ver. ver 1.2s // //----------------------------------------------------------------------------// // Description : // //----------------------------------------------------------------------------`timescale 1ns / 1ns module SPI_Master_tb; //Internal signals declarations: tri [7:0]data_bus_bidir; reg [7:0]data_bus; //Continous assignment for inout port "data_bus". assign data_bus_bidir = data_bus; reg reg reg reg reg reg pro_clk; miso; [1:0]addr; CS; WR; RD; wire mosi; wire sclk; wire [7:0]ss; 16 // Unit Under Test port map SPI_Master UUT ( .data_bus(data_bus_bidir), .pro_clk(pro_clk), .miso(miso), .addr(addr), .CS(CS), .WR(WR), .RD(RD), .mosi(mosi), .sclk(sclk), .ss(ss)); always begin #5 pro_clk = ~pro_clk; end initial $monitor($realtime,,"ps %h %h %h %h %h %h %h ",data_bus_bidir,pro_clk,miso,addr,CS,WR,RD,mosi,sclk,ss,control); %h %h %h initial begin end initial begin pro_clk =0; data_bus=8'b11101000; addr=2'b00; CS=1; WR=1; RD=0; miso=1; #30 WR=0; data_bus=8'b00110011; addr=2'b10; #500 WR=0; data_bus=8'b01010101; #5 WR=1; #500 WR=0; addr=2'b11; #5 RD=1; end endmodule Для моделирования использовался САПР Aldec Active-HDL 8.3. В начале работы происходит настройка блока: выбирается режимы работы CPHA, CPOL, выбирается делитель частоты, выбирается Slave-устройство, с которым будет проходить дальнейший обмен информацией. Временная диаграмма процесса настройки блока показана на рисунке 2.3.1. 17 Рисунок 2.3.1 – Временная диаграмма настройки параметров работы блока SPI_master Настройка режимов работы CPHA, CPOL, выбор делитель частоты, выбор ведомого устройства осуществляется путём записи в регистр control байта настройки блока. Запись в регистр настройки происходит когда управляющий сигнал addr принимает значение 00. После записи сигнал addr принимает значение 10, при котором поступающие от процессора на вход блока данные уже не записываются в регистр control а поступают в сдвиговый регистр, с которого идёт передача на линию MOSI. Временная диаграмма передачи числа 0х33 (00110011) показана на рисунке 2.3.2. Рисунок 2.3.2 – Временная диаграмма передачи числа 0х33 (00110011) 18 В качестве теста, следующим числом передается число 0х55 (01010101). Временная диаграмма передачи показана на рисунке 2.3.3. Рисунок 2.3.3 – Временная диаграмма передачи числа 0х55 (01010101) В соответствии с выбранными ранее режимами работы блока, данные выставляются на линию MOSI по заднему фронту тактового сигнала SCL, запись ведомым устройством при этом осуществляется по переднему фронту тактового сигнала, таким образом гарантируя точное считывание бита. После передачи байта информации линия MOSI сновы переходит в неопределённое состояние. 2.4 Синтезирование блока SPI-master на языке HDL. Синтез блока проводился для ПЛИС Spartan 3 (XC3S1500) , для этого использовался САПР ISE WEB PACK. По результатам компиляции и синтеза был получен отчёт: 19 Из отчёта следует, что разработанный блок занимает на ПЛИС 24 логических ячеек из 221 возможных, что составляет 10%. Средствами САПР была получена схема расположения логических ячеек а кристалле (рис. 2.4.1). Рисунок 2.4.1 – Схема расположения логических блоков на ПЛИС Так же инструментом Pin Planer произведена автоматическая трассировка кристалла и сигналам были назначены вывода ПЛИС (рис.2.4.2). 20 Рисунок 2.4.2 – Схема трассировки кристалла Выводы В работы был разработан блок SPI_master с возможностью настройки режимов работы (фаза и полярность сигнала), с возможностью выбора до 8 ведомых устройств. По результатам синтеза разработанный блок занимает на ПЛИС 24 логических ячеек из 221 возможных, что составляет 10%. Средствами САПР IST WEBPACK был проведено размещение логических блоков на кристалле и трассировка. 21