реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> Внешние прерывания, STM32F103VB
Jenya7
сообщение Jul 29 2014, 13:52
Сообщение #31


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Golikov A. @ Jul 29 2014, 19:41) *
ПЛИС надо ставить...

Я кстати это предложил в беседе с моим товарищем. Но тут возникает другая проблема - сопряжение с внешним миром. Скажем мне нужен UART. Сделать UART на FPGA не проблема но имплементировать полный парсер и работу со стрингами это адский труд если вообще такое реально сделать.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 29 2014, 19:02
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ага, где то полдня работыsm.gif...
у нас 5 моторами рулит ПЛИС и АРМ, АРМ - езернет со стэком и всей фигней, по 2 SSP (аналог SPI) он общается с ПЛИС.
В ПЛИС автоматы которые все делают, на протоколе даже контрольная сумма есть...
SPI много легче UART в случае плис, а протокол может быть простейшим, АДРЕС, НАПРАВЛЕНИЕ (чтение-запись), ДАННЫЕ (фиксированной длинны 32 бита), контрольная сумма...
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 29 2014, 19:23
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



А если вместо ПЛИС поставить мелкоту, типа STM32F0xx?
Там и таймеров - что ног не хватит. И трехфазные комплиментарные выходы с аппаратным deadtime. И возможность энкодер подключить.
Плюс всякие аналоговые компараторы для защит.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 30 2014, 05:20
Сообщение #34


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Golikov A. @ Jul 30 2014, 01:02) *
ага, где то полдня работыsm.gif...
у нас 5 моторами рулит ПЛИС и АРМ, АРМ - езернет со стэком и всей фигней, по 2 SSP (аналог SPI) он общается с ПЛИС.
В ПЛИС автоматы которые все делают, на протоколе даже контрольная сумма есть...
SPI много легче UART в случае плис, а протокол может быть простейшим, АДРЕС, НАПРАВЛЕНИЕ (чтение-запись), ДАННЫЕ (фиксированной длинны 32 бита), контрольная сумма...

Может подгоните имплементацию парсера комманд на ПЛИС? sm.gif

Цитата(adnega @ Jul 30 2014, 01:23) *
А если вместо ПЛИС поставить мелкоту, типа STM32F0xx?
Там и таймеров - что ног не хватит. И трехфазные комплиментарные выходы с аппаратным deadtime. И возможность энкодер подключить.
Плюс всякие аналоговые компараторы для защит.

Это кстати очень даже рабочее решение. У меня были проекты с двумя контроллерами, так сказать parallel tasking.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 30 2014, 06:19
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Может подгоните имплементацию парсера комманд на ПЛИС

Если возьмете как есть, то есть сами будите разбираться что там и зачем сделано, легкоsm.gif
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 30 2014, 06:27
Сообщение #36


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Golikov A. @ Jul 30 2014, 12:19) *
Если возьмете как есть, то есть сами будите разбираться что там и зачем сделано, легкоsm.gif

Я писал под ПЛИС, нет проблем разобраться в коде. sm.gif
Go to the top of the page
 
+Quote Post
adnega
сообщение Jul 30 2014, 06:35
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(Jenya7 @ Jul 30 2014, 09:20) *
Это кстати очень даже рабочее решение. У меня были проекты с двумя контроллерами, так сказать parallel tasking.

STM32F030K6T6 по $1. Можно и не один поставить при желании)

ПЛИС, может, и хорошо, но дорого. И для меня (только начавшего вникать в ПЛИС) много вопросов в синхронизации разных частей проекта -
т.е. нужно заниматься более низкоуровневым проектированием (типа, как на ASM для схем пересесть).
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 30 2014, 07:03
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



да фигня... общий принцип перевести все входы под единый клок внутри ПЛИС и забыть об этом.

CODE

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: ***
// Engineer: ***
//
// Create Date: ***
// Design Name:
// Module Name: SPIComModule
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
// "spi_cs" and "data_rdy" signal must be in
// stable state before any "spi_clk" actions
// min 2 "clk" for "data_rdy"
// and 2 "clk" for "spi_cs"
//
//////////////////////////////////////////////////////////////////////////////////
module SPIComModule_v4_00(
clk, //основной клок

spi_cs, //сигнал выбора SPI
spi_clk, //SPI клок данных
spi_in, //входные данные SPI
spi_out, //выходные данные SPI

module_sel, //выбор модуля
submodule_sel, //выбор подмодуля
data_to_module, //данные для модуля
data_from_module, //данные от модуля

wr_rd_sync, //сигнал синхронизации чтения - записи
wr_strb, //строб записи
wr_ack, //подтверждение записи
rd_strb, //строб чтения
rd_ack, //подтверждение чтения

check_sum_ok, //сигнал подтверждения правильной контрольной суммы
data_write_done, //сигнал подтверждения записи данных
data_rdy //сигнал готовности данных для чтения
);

//================================================================================
==
parameter MODULE_DATA_SIZE = 32; //размер данных модуля
parameter MODULE_ADDR_SIZE = 4; //размер поля адреса
parameter MODULE_ADDR_VECTOR_SIZE = (32'b01 << MODULE_ADDR_SIZE); //размер вектора выбора модуля (4 бита адрес)
parameter SUB_ADDR_SIZE = 3; //размер поля подадреса
parameter SUB_ADDR_VECTOR_SIZE = (32'b01 << SUB_ADDR_SIZE); //размер вектора выбора подмодуля (3 бита подадрес)

parameter READ_DIRRECTION_VAL = 1; //значение бита при котором идет чтение

parameter ADDR_FIELD_SIZE = 8; //8 бит поле адреса
parameter CHECKSUM_FIELD_SIZE = 8; //8 бит поле контрольной суммы
localparam DATA_FIELD_SIZE = MODULE_DATA_SIZE; //размер поля данных

//размер регистра расчета длинны сообщения для определения
//окончания приема
parameter MES_LEN_COUNTER_SIZE = 6;

//размер регистра расчета длинны слова контрольной суммы
//для определения окончания приема очередного слова
parameter CHECKSUM_LEN_COUNTER_SIZE = 3;

//контрольная сумма по всем сообщению должна дать 0
//чтобы полностью нулевое сообщение не прошло как верное
//начинаем считать сумму с этого значения
parameter START_CHECKSUM_VAL = 'hA5;

//================================================================================
==
input clk;

input spi_cs;
input spi_clk;
input spi_in;
output spi_out;

output reg [MODULE_ADDR_VECTOR_SIZE - 1 : 0] module_sel = 0;
output reg [SUB_ADDR_VECTOR_SIZE - 1 : 0] submodule_sel = 0;
output reg [MODULE_DATA_SIZE - 1 : 0] data_to_module = 0;
input [MODULE_DATA_SIZE - 1 : 0] data_from_module;

//этот сигнал должен быть лишен мета-стабильности
//во внешних схемах
input wr_rd_sync;

output wr_strb;
input wr_ack;
output rd_strb;
input rd_ack;

output reg check_sum_ok = 0;
output reg data_write_done = 0;
output reg data_rdy = 0;

//================================================================================
==
//регистры для задания состояние строба чтения и записи
//эти регистры задает схема, а выходное значение получается
//с учетом сигнала синхронизации
reg wr_strb_reg = 0;
reg rd_strb_reg = 0;

//если разрешена запись или чтение, выдаем наружу стробы
assign wr_strb = (wr_strb_reg & wr_rd_sync);
assign rd_strb = (rd_strb_reg & wr_rd_sync);

//для синхронизации 2 клоковых доменов
//основного и SPI используем систему семафоров
//задание и подтверждение задания
reg need_start_recive = 0; //необходимо начать прием с 1 клоком SPI
reg need_start_recive_ack = 0; //подтверждение, прием начат

reg recive_done = 0; //окончание приема
//так как сигнал из другого клокового домена
//пропустим его через 2 триггера, это создаст
//доп задержку на стабилизацию данных
//по констрайнам частота процессора в 2 раза выше частоты SPI
//значит через 2 клока данные SPI гарантированно верны
reg recive_done_1 = 0;
reg recive_done_2 = 0;
reg recive_done_ack = 0; //подтверждение окончания приема

reg need_start_transllate = 0; //необходимо начать передачу данных
reg need_start_transllate_ack = 0; //передача данных начата


//вектор входного сообщения
localparam FULL_MESSAGE_LEN = ADDR_FIELD_SIZE + DATA_FIELD_SIZE + CHECKSUM_FIELD_SIZE;
reg [FULL_MESSAGE_LEN - 1 : 0] input_data_vector = 0;
//для удобства работы разделим поля входного вектора
wire [DATA_FIELD_SIZE - 1 : 0] data_w;
assign data_w = input_data_vector[DATA_FIELD_SIZE + CHECKSUM_FIELD_SIZE - 1 -: DATA_FIELD_SIZE];
wire [SUB_ADDR_SIZE - 1 : 0] subaddr_w;
assign subaddr_w = input_data_vector[SUB_ADDR_SIZE + DATA_FIELD_SIZE + CHECKSUM_FIELD_SIZE - 1 -: SUB_ADDR_SIZE];
wire [MODULE_ADDR_SIZE - 1 : 0 ] addr_w;
assign addr_w = input_data_vector[MODULE_ADDR_SIZE + SUB_ADDR_SIZE + DATA_FIELD_SIZE + CHECKSUM_FIELD_SIZE - 1 -: MODULE_ADDR_SIZE];
wire read_direction_w;
assign read_direction_w = input_data_vector[1 + MODULE_ADDR_SIZE + SUB_ADDR_SIZE + DATA_FIELD_SIZE + CHECKSUM_FIELD_SIZE - 1 -: 1];


//вектор расчета контрольной суммы
reg [CHECKSUM_FIELD_SIZE - 1 : 0] checksum_calc_vector = START_CHECKSUM_VAL;
//вектор приема данных для расчета контрольной суммы
reg [CHECKSUM_FIELD_SIZE - 1 : 0] checksum_vector = 0;
//вектор выходных данных, на 1 бит меньше чем данные
//так как первый отправляемый бит в него не сохраняется
reg [DATA_FIELD_SIZE - 2 : 0] output_vector = 0;
//значение выходного бита данных SPI должно быть готово
//до первого клока, еще до защелки данных в сдвиговый регистр
//поэтому первый бит берется из входного вектора
//а последующие уже из сдвигового регистра
//в начальный момент будет стоять семафор
assign spi_out = (need_start_transllate != need_start_transllate_ack) ?
data_from_module [MODULE_DATA_SIZE - 1] : //начальный момент
output_vector[MODULE_DATA_SIZE - 2]; //последующие посылки (вектор на 1 бит меньше данных)


//счетчик длинны сообщения
reg [MES_LEN_COUNTER_SIZE - 1 : 0] mes_len_counter = 0;
//счетчик длинны слова контрольной суммы
reg [CHECKSUM_LEN_COUNTER_SIZE - 1 : 0] checksum_len_counter = 0;


//================================================================================
==
// обработка основного клока
//================================================================================
==
always @(posedge clk)
begin
//-------------------- переход между клоковыми доменами
recive_done_1 <= recive_done;
recive_done_2 <= recive_done_1;


//-------------------- обмен данными
if(spi_cs == 1'b1) //если нет выбора SPI
begin
//чип селект имеет гарантированную паузу, он асинхронный
//гарантированная пауза приведет схему в правильное состояние
//выборы адреса - one hot, один бит в векторе,
//при снятии не может так получиться что бит измениться
//или возникнут еще какие-то соседние биты,
//потому даже если адрес изменится до снятия wr(rd)_strb
//так как сигнал cs асинхронный, это не страшно, другие
//адреса не выберутся и неправильных транзакций не будет
//значение битов ответов тоже не важно, если чип селект
//вверху их уже не проверяют

//подготовимся к приему следующего сообщения
//первый фронт SPI клока - начало приема
need_start_recive <= ~need_start_recive_ack;

//снимем все стробы
wr_strb_reg <= 0;
rd_strb_reg <= 0;

//снимем все выборы,
module_sel <= 0;
submodule_sel <= 0;

//снимаем все ответы
check_sum_ok <= 0;
data_write_done <= 0;
data_rdy <= 0;

//на всякий случай, если было поднятие чипселекта
//до окончания обмена, снимем флаг окончания приема
recive_done_ack <= recive_done_2;
end
else //если есть выбор SPI
begin
if(recive_done_2 != recive_done_ack) //если закончен прием
begin
//ставим подтверждение обработки флага
recive_done_ack <= recive_done_2;

//если сошлась контрольная сумма
//последние сложение надо сделать в этой процедуре
//так как после приема последнего бита
//нет больше тактов (клоков SPI) на выполнение
if((checksum_calc_vector + checksum_vector) == {CHECKSUM_FIELD_SIZE{1'b0}})
begin
check_sum_ok <= 1'b1; //ставим признак

//ставим выбор модуля и подадреса
//сразу производим частичную дешифрацию адреса
module_sel <= ({{(MODULE_ADDR_VECTOR_SIZE - 1){1'b0}}, 1'b1} << $unsigned (addr_w));
submodule_sel <= ({{(SUB_ADDR_VECTOR_SIZE - 1){1'b0}}, 1'b1} << $unsigned (subaddr_w));

if(read_direction_w == READ_DIRRECTION_VAL) //если режим чтения
begin
rd_strb_reg <= 1'b1; //строб чтения
//отмечаем что нужно будет начать передачу
//захват данных в регистр произойдет по
//SPI клоку, а его выдаст мастер только после
//получения сигнала готовности данных
//так что это значение можно тут выставить
//и не заботится о нем, даже если будет прерывание обмена
//без фазы чтения
need_start_transllate <= ~need_start_transllate_ack;
end
else //режим записи
begin
data_to_module <= data_w; //выставляем данные
wr_strb_reg <= 1'b1; //строб записи
end
end //контрольная сумма
end //закончен прием

//если не будет признака окончания приема
//не будет проверки контрольной суммы
//и не будет запросов на чтение или запись
//и сигналы ниже не появятся

//если есть запрос на запись и подтверждение
if((wr_strb_reg == 1'b1)&&(wr_ack == 1'b1))
data_write_done <= 1'b1; //отмечаем что данные записаны

//если есть запрос на чтение и подтверждение
if((rd_strb_reg == 1'b1)&&(rd_ack == 1'b1))
data_rdy <= 1'b1; //отмечаем что данные готовы

end //есть выбор SPI
end //конец обработки клока


//================================================================================
==
// обработка клока SPI
//================================================================================
==
//выбор SPI не проверяем, так как без выбора не
//пройдет конец обмена, весь обмен идет внутри
//одного выбора, клоков вне обмена нет
always @(posedge spi_clk)
begin

//----------------------------------------------------------------
if (need_start_recive != need_start_recive_ack) //если начало приема ы
begin
//отмечаем начало приема
need_start_recive_ack <= need_start_recive;
//сохраняем первый принятый бит
input_data_vector <= {{(FULL_MESSAGE_LEN - 1){1'b0}},spi_in};
checksum_vector <= {{(CHECKSUM_FIELD_SIZE - 1){1'b0}},spi_in};
//сохраняем начальное значение вектора расчета контрольной суммы
checksum_calc_vector <= START_CHECKSUM_VAL;

//заряжаем счетчики, первый бит уже принят,
//окончание приема всего сообщения по равенству нулю
//счетчик всего сообщения на 1 бит меньше чтобы
//он стал нулем в момент приема последнего бита
//а не после приема, вместе с приемом последнего
//бита выставиться и признак окончания приема
mes_len_counter <= (FULL_MESSAGE_LEN - 2);
checksum_len_counter <= (CHECKSUM_FIELD_SIZE - 1);

end
else //прием
begin
//уменьшаем счетчики с каждым принятым битом
mes_len_counter <= mes_len_counter - 1'b1;
checksum_len_counter <= checksum_len_counter - 1'b1;

//прием сообщения, сдвигаем входной вектор дополняя входным битом
input_data_vector <= {input_data_vector[FULL_MESSAGE_LEN - 2 : 0], spi_in};
//параллельно сохраняем вектор контрольной суммы
checksum_vector <= {checksum_vector [CHECKSUM_FIELD_SIZE - 2 : 0], spi_in};

//если приняли все сообщение
if(mes_len_counter == 0)
recive_done <= ~recive_done_ack; //отмечаем окончание приема

//если приняли очередное слово контрольной суммы
if(checksum_len_counter == 0)
begin
//заряжаем счетчик заново
checksum_len_counter <= (CHECKSUM_FIELD_SIZE - 1);
//добавляем принятый вектор в сумму
checksum_calc_vector <= checksum_calc_vector + checksum_vector;
end
end //прием

//-----------------------------------------------------------------
//значение передаваемых данных во время приема не важны,
//потому всегда передаем, к фазе передачи данные будут
//запрошены и корректно обновлены
if (need_start_transllate != need_start_transllate_ack) //если начало передачи
begin
//отмечаем начало передачи
need_start_transllate_ack <= need_start_transllate;
//сохраняем данные от модуля без старшего бита,
//так как первый бит уже передан (взят из данных на отправку)
//после этого такта, на выход будет передаваться старший бит
//этого вектора
output_vector <= data_from_module[DATA_FIELD_SIZE - 2 : 0];
end
else //передача
begin
//просто сдвигаем вектор данных
//значение дополнения не важно
output_vector <= (output_vector << 1);
end //передача

end //конец обработки клока SPI

endmodule



wr_rd_sync - этот сигнал в 1 зажмите, он для синхронизации служит, это для нашей специфики было нужно.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 30 2014, 07:07
Сообщение #39


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(adnega @ Jul 30 2014, 12:35) *
STM32F030K6T6 по $1. Можно и не один поставить при желании)

ПЛИС, может, и хорошо, но дорого. И для меня (только начавшего вникать в ПЛИС) много вопросов в синхронизации разных частей проекта -
т.е. нужно заниматься более низкоуровневым проектированием (типа, как на ASM для схем пересесть).


ПЛИС очень сильная штука. Во первых real time действительно real - несколько процессов могут бежать параллельно. Во вторых полная свобода выбора ног - куда посадить рвм, куда энкодер - соответственно разводка платы существенно оптимизируется. Кроме того как говорят надежней в работе. Ну конечно пересесть с С на VHDL тут придется немного попотеть.


Golikov A.,
Большое спасибо !
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 30 2014, 07:14
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Огромный бонус ПЛИС - это возможность создание реально параллельных блоков, а еще в добавок там куча памяти теперь и прочих радостей. Можно и проц запихать, отказавшись от внешнего. Для частной маленькой задачи обработки энкодеров можно взять малюсенькую CPLD.

Я вот тут пытался представить как обработать энкодер на таймере, у меня не получилось 4 электронных отсчетов на реальную линию, и направление надо учитывать, а в ПЛИС все будет четко, 4 электронных отсчета на реальный, и регистры накопления внутри ПЛИС.

да еще забыл

spi_clk - вот этот сигнал лучше завести на клоковый вход ПЛИС (это спец ножки, их много). Можно и на обычный, но времянка просядет, на клоковый лучше.

И я вам настоятельно рекомендую пересаживаться на Verilog, я начинал с VHDL, а теперь на верилог пересел, одни положительные эмоции

во я еще тестбенч нашел от модуляsm.gif

CODE

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 15:18:31 04/16/2014
// Design Name: SPIComModule_v4_00
// Module Name: E:/SYNC_MOTOR/FPGA/SPIComModule_v4_00_tb.v
// Project Name: SyncMotor
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: SPIComModule_v4_00
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////

module SPIComModule_v4_00_tb;
localparam DATA_SIZE = 16;

// Inputs
reg clk;
reg spi_cs;
reg spi_clk;
reg spi_in;
reg [DATA_SIZE - 1 : 0] data_from_module;
reg wr_rd_sync;
reg wr_ack;
reg rd_ack;

// Outputs
wire spi_out;
wire [15:0] module_sel;
wire [7:0] submodule_sel;
wire [DATA_SIZE - 1 : 0] data_to_module;
wire wr_strb;
wire rd_strb;
wire check_sum_ok;
wire data_write_done;
wire data_rdy;

reg [DATA_SIZE - 1 : 0] datareg_00;
reg [DATA_SIZE - 1 : 0] datareg_01;
reg [DATA_SIZE - 1 : 0] datareg_10;
reg [DATA_SIZE - 1 : 0] datareg_11;

reg [DATA_SIZE - 1 : 0] data ;
reg [7 : 0] addr ;
reg [7 : 0] check_sum;

// Instantiate the Unit Under Test (UUT)
SPIComModule_v4_00
#(.MODULE_DATA_SIZE(DATA_SIZE)
)
uut
(
.clk(clk),
.spi_cs(spi_cs),
.spi_clk(spi_clk),
.spi_in(spi_in),
.spi_out(spi_out),
.module_sel(module_sel),
.submodule_sel(submodule_sel),
.data_to_module(data_to_module),
.data_from_module(data_from_module),
.wr_rd_sync(wr_rd_sync),
.wr_strb(wr_strb),
.wr_ack(wr_ack),
.rd_strb(rd_strb),
.rd_ack(rd_ack),
.check_sum_ok(check_sum_ok),
.data_write_done(data_write_done),
.data_rdy(data_rdy)
);

integer i;

initial begin
// Initialize Inputs
spi_cs = 0;
spi_clk = 0;
spi_in = 0;
wr_rd_sync = 0;
data = 0;
addr = 0;
check_sum = 0;

// Wait 100 ns for global reset to finish
#100;

// Add stimulus here
spi_cs <= 1;
spi_clk <= 1;

#100;


//-----------------------------------------------------------
data = 16'h0000;
addr = 8'b10010001;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 0;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;
wr_rd_sync = 1;
#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------






//-----------------------------------------------------------
#50;
data = 16'hAABB;
addr = 8'b00001001;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 1;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------




//-----------------------------------------------------------
#50;
data = 16'hCCDD;
addr = 8'b00010010;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 1;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------


//-----------------------------------------------------------
#50;
data = 16'hAABB;
addr = 8'b10001001;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 1;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------

//-----------------------------------------------------------
#50;
data = 16'hAABB;
addr = 8'b10010010;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 1;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------



//-----------------------------------------------------------
#50;
data = 16'hEEFF;
addr = 8'b00000000;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 1;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------

//-----------------------------------------------------------
#50;
data = 16'h0000;
addr = 8'b10000000;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 1;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------


#1000;



//-----------------------------------------------------------
#50;
data = 16'hCCCC;
addr = 8'b10010010;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 0;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------



//-----------------------------------------------------------
#50;
data = 16'hCCCC;
addr = 8'b00000000;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 0;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------

//-----------------------------------------------------------
#50;
data = 16'h0000;
addr = 8'b10000000;
check_sum = 8'hFF + data[7:0] + data[15:8] + addr;
check_sum = 0 - check_sum;

wr_rd_sync = 0;
spi_cs <= 0;

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = addr[7-i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = data[DATA_SIZE - 1 -i];
#2;
spi_clk = 1;
#10;
end

for (i=0;i<8;i=i+1)
begin
spi_clk = 0;
#8;
spi_in = check_sum[7-i];
#2;
spi_clk = 1;
#10;
end

#100;

if(data_rdy == 1)
for (i=0;i<DATA_SIZE;i=i+1)
begin
spi_clk = 0;
#10;
spi_clk = 1;
#10;
end

spi_cs <= 1;
//-----------------------------------------------------------

end


initial begin
// Initialize Inputs
clk = 0;

// Wait 100 ns for global reset to finish
#98;

// Add stimulus here
forever begin
#5;
clk <= ~clk;
end

end

initial begin
// Initialize Inputs
datareg_00 = 0;
datareg_01 = 0;
datareg_10 = 0;
datareg_11 = 0;
wr_ack = 0;
rd_ack = 0;
data_from_module = 0;

// Wait 100 ns for global reset to finish
#100;

// Add stimulus here
forever begin
#1;
wr_ack <= 0;
rd_ack <= 0;
data_from_module <= 'hFFFF;

if((module_sel == 2'b1)&&(submodule_sel == 2'b1))
begin
if(wr_strb == 1)
begin
datareg_00 <= data_to_module;
wr_ack <= 1;
end
if(rd_strb == 1)
begin
data_from_module <= datareg_00;
rd_ack <= 1;
end
end

if((module_sel == 2'b10)&&(submodule_sel == 2'b1))
begin
if(wr_strb == 1)
begin
datareg_10 <= data_to_module;
wr_ack <= 1;
end
if(rd_strb == 1)
begin
data_from_module <= datareg_10;
rd_ack <= 1;
end
end


if((module_sel == 2'b1)&&(submodule_sel == 2'b10))
begin
if(wr_strb == 1)
begin
datareg_01 <= data_to_module;
wr_ack <= 1;
end
if(rd_strb == 1)
begin
data_from_module <= datareg_01;
rd_ack <= 1;
end
end

if((module_sel == 2'b10)&&(submodule_sel == 2'b10))
begin
if(wr_strb == 1)
begin
datareg_11 <= data_to_module;
wr_ack <= 1;
end
if(rd_strb == 1)
begin
data_from_module <= datareg_11;
rd_ack <= 1;
end
end

end

end


endmodule


Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 30 2014, 07:30
Сообщение #41


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Перед тем как начать програмироать на ПЛИС я читал много статей VHDL vs Verilog - все таки общий тренд в пользу VHDL.
Go to the top of the page
 
+Quote Post
DmitryM
сообщение Jul 30 2014, 07:59
Сообщение #42


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



Цитата(Jenya7 @ Jul 30 2014, 11:30) *
Перед тем как начать програмироать на ПЛИС я читал много статей VHDL vs Verilog - все таки общий тренд в пользу VHDL.

Добавлю еше что VHDL ГОСТирован, а Verilog - нет. общий тренд в пользу VHDL.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 30 2014, 09:23
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Поскольку мне надо делать дело, а не быть в тренде я выбираю Verilog sm.gif
Это священная война, и вы можете выбирать любую сторону.

Я выбрал верилог по причине того что писать на нем легче, меньше букв, меньше атавистических библиотек которые перекрывают друг друга вызывая путаницы и несостыковки проекта. VHDL - старинный монстр, который несет на себе груз не только работы с ПЛИС, но и общего описания железа, в нем можно описать все что хочешь и максимально строго, плата за это что там надо топтать клавиатуру не по детски, и самая простая схема требует много букв. Если же ограничиться только работой с ПЛИС, то верилога 100% хватит, и писать будет удобнее. Общая тенденция что плисовики знают оба языка, потому что они представленны одинаково на рынке, а с какого начать вам решать)
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 17:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01545 секунд с 7
ELECTRONIX ©2004-2016