jenya7 0 5 февраля, 2017 Опубликовано 5 февраля, 2017 (изменено) · Жалоба Что то я запутался. У меня есть SPI модуль. entity GENERIC_SPI is port( RST :In Std_logic ; --Main DSP system reset. CLK :In Std_logic ; --DSP MAin Clock to be divided. SPI_nCS :In Std_logic ; SPI_CLK :Out Std_logic; SPI_MasterOut :Out Std_logic; SPI_MasterIn :In Std_logic; SPI_CTRL_REG :In Std_logic_vector(2 downto 0) ;--bit0 = CPHA bit1 = CPOL bit2 = MSBnLSB_FIRST SPI_BAUD_DIV :In Std_logic_vector(15 downto 0) ; SPI_DATA_LENGTH :In Std_logic ; SPI_Wr_Data :In Std_logic_vector(15 downto 0) ; --Signal coming from REG_FILE SMI_Wr_Data_Reg SPI_Rd_Data :Out Std_logic_vector(15 downto 0) ; --Signal going to REG_FILE SPI_Wr_Start_Trig :In Std_logic ; --DSP MAin Clock to be divided. SPI_Rd_Start_Trig :In Std_logic ; --DSP MAin Clock to be divided. SPI_Data_Ready :Out Std_logic ; SPI_Data_Ready_Clear:In Std_logic ; SPI_Wr_DONE :Out Std_logic ; SPI_Wr_DONE_Clear :In Std_logic ; SPI_WR_En :Out Std_logic ; SPI_Data_Count :Out Std_logic_vector(15 downto 0) --SPI_Counter_Reset :In Std_logic ); end GENERIC_SPI; architecture STRUCTURE of GENERIC_SPI is Signal CLK_DIV :Std_logic_vector(15 downto 0) := (others=>'0'); Signal CLK_RISE :Std_logic := '0'; Signal CLK_FALL :Std_logic := '0'; Signal CLK_EN :Std_logic := '0'; Signal CLK_EN_ACTIVE_Trig :Std_logic := '0'; Signal CLK_EN_FALL_COUNTER :Std_logic_vector(3 downto 0) := (others=>'0'); Signal ShiftCount :Std_logic_vector(3 downto 0) := (others=>'0'); Signal SPI_CLK_reg :Std_logic := '0'; Signal SPI_RdnWr :Std_logic := '0'; Signal SPI_Z_Out :Std_logic := '0'; Signal SPI_Start_Trig_d :Std_logic := '0'; Signal SPI_SIO_out :Std_logic := '0'; Signal SPI_Wr_Data_ShiftReg :Std_logic_vector(15 downto 0) ; --Shift Reg for parallel2Serial COnversion of Data(MSB First) Signal SPI_Rd_Data_ShiftReg :Std_logic_vector(15 downto 0) ; --Shift Reg for Serial2parallel COnversion of Data recived from switchdevice(MSB First) Signal SPI_Data_Count_reg : Std_logic_vector(15 downto 0) := (others=>'0'); Signal SPI_nCS_reg :Std_logic := '0'; Signal Next_Clk_FALL_nRAISE :Std_logic := '0'; Signal CPHA :Std_logic := '0'; Signal CPOL :Std_logic := '0'; Signal MSBnLSB_FIRST :Std_logic := '0'; Signal Pos_Clk_Out :Std_logic := '0'; Signal Neg_Clk_Out :Std_logic := '0'; Signal SPI_DATA_LENGTH_DEF :Std_logic_vector(3 downto 0) := (others=>'0'); Type StateType is (ST_Idle,ST_WAIT_FOR_FALL,ST_FIRST_LOAD,ST_WAIT_FOR_LOAD,ST_WAIT_FOR_SAMP,ST_END _SAMP_REG); Signal State :StateType; begin CPHA <= SPI_CTRL_REG(0) ; CPOL <= SPI_CTRL_REG(1) ; MSBnLSB_FIRST <= SPI_CTRL_REG(2) ; SPI_Data_Count <= SPI_Data_Count_reg ; SPI_WR_En <= '0' ;--Not in use yet SPI_Data_Ready <= '0' ;--Not in use yet process (SPI_DATA_LENGTH,SPI_Wr_Data_ShiftReg) begin if (SPI_DATA_LENGTH='0') then SPI_DATA_LENGTH_DEF <=X"7" ; SPI_MasterOut <= SPI_Wr_Data_ShiftReg(7); else SPI_DATA_LENGTH_DEF <=X"F" ; SPI_MasterOut <= SPI_Wr_Data_ShiftReg(15); end if; end process; process (CLK,RST) begin if (RST='1') then Pos_Clk_Out <='0' ; Neg_Clk_Out <='1' ; elsif (CLK'event and CLK='1') then if (CLK_EN='1') then Pos_Clk_Out <=SPI_CLK_reg ; Neg_Clk_Out <=not(SPI_CLK_reg) ; else Pos_Clk_Out <='0' ; Neg_Clk_Out <='1' ; end if; end if; end process; process (CPOL,Pos_Clk_Out,Neg_Clk_Out) begin if (CPOL='0') then SPI_CLK <=Pos_Clk_Out ; else SPI_CLK <=Neg_Clk_Out ; end if; end process; process (CLK,RST) begin if (RST='1') then CLK_EN <= '0'; CLK_EN_FALL_COUNTER <= (others=>'0'); elsif (CLK'event and CLK='1') then if (CLK_EN_ACTIVE_Trig = '1' )then CLK_EN <= '1'; CLK_EN_FALL_COUNTER <= X"0"; end if; if ( (CLK_FALL = '1')and (CLK_EN = '1') )then CLK_EN_FALL_COUNTER <= (CLK_EN_FALL_COUNTER +1); if (CLK_EN_FALL_COUNTER = SPI_DATA_LENGTH_DEF )then CLK_EN <= '0'; CLK_EN_FALL_COUNTER <= (others=>'0'); end if; end if; end if; end process; ---------------------------------------------------------- -- Clock Divider, Generates CLK_RISE,CLK_FALL signals process (CLK,RST) begin--reset changed to be asynchronus not like in a2d module. if (RST='1') then CLK_DIV <= (others=>'0'); --reset changed to be asynchronus not like in a2d module. SPI_CLK_reg <= '0'; -- Keep CLK = '0'---might changed not like d2a CLK_RISE <= '0'; CLK_FALL <= '0'; Next_Clk_FALL_nRAISE <= '0'; elsif (CLK'event and CLK='1') then CLK_DIV <= CLK_DIV + 1; if (CLK_DIV = SPI_BAUD_DIV ) then CLK_DIV <= (others=>'0'); SPI_CLK_reg <= not(SPI_CLK_reg); Next_Clk_FALL_nRAISE <= not(Next_Clk_FALL_nRAISE); if (Next_Clk_FALL_nRAISE = '0') then CLK_RISE <= '1'; elsif (Next_Clk_FALL_nRAISE = '1') then CLK_FALL <= '1'; end if; else CLK_RISE <= '0'; CLK_FALL <= '0'; end if; end if; end process; ---------------------------------------------------------- process (CLK,RST) begin if (RST='1') then State <= ST_Idle; CLK_EN_ACTIVE_Trig <= '0'; SPI_Rd_Data <= (others=>'0') ;-- update output when idle ShiftCount <= (others=>'0');--Load value of 15 to hiftCount because address word to send is 14 bit (without TA) SPI_Wr_Data_ShiftReg <= (others=>'0'); SPI_Rd_Data_ShiftReg <= (others=>'0'); SPI_Wr_DONE <= '0'; SPI_Data_Count_reg <= (others=>'0') ; -- SPI_MasterOut <= '0' ; elsif (CLK'event and CLK='1') then case State is -------------------------------- When ST_Idle => CLK_EN_ACTIVE_Trig <= '0'; --SPI_Rd_Data<=SPI_Rd_Data_ShiftReg ;-- update output when idle ShiftCount <= (others=>'0');--Load value of 15 to hiftCount because address word to send is 14 bit (without TA) SPI_Rd_Data_ShiftReg <= (others=>'0'); SPI_Wr_Data_ShiftReg <= (others=>'0'); if (SPI_Wr_Start_Trig = '1') then State <= ST_WAIT_FOR_FALL; SPI_Wr_Data_ShiftReg<=SPI_Wr_Data;--//load data --Counter <= 0XXXX000 end if; if (SPI_Wr_DONE_Clear = '1') then SPI_Wr_DONE <= '0'; --Counter <= 0XXXX000 end if; When ST_WAIT_FOR_FALL => CLK_EN_ACTIVE_Trig <= '0'; if(CLK_FALL = '1') then CLK_EN_ACTIVE_Trig <= '1'; if(CPHA = '0')then State <= ST_WAIT_FOR_SAMP; SPI_Wr_Data_ShiftReg <= SPI_Wr_Data; ShiftCount <= (others=>'0'); State <= ST_FIRST_LOAD; end if; end if; When ST_FIRST_LOAD => CLK_EN_ACTIVE_Trig <= '0'; if(((CPHA = '1') and (CLK_RISE = '1'))) then State <= ST_WAIT_FOR_SAMP; SPI_Wr_Data_ShiftReg <= SPI_Wr_Data; ShiftCount <= (others=>'0'); end if; if (CLK_FALL = '1')then CLK_EN_ACTIVE_Trig <= '1'; end if; When ST_WAIT_FOR_LOAD => CLK_EN_ACTIVE_Trig <= '0'; if( ((CPHA = '0') and (CLK_FALL = '1')) or ((CPHA = '1') and (CLK_RISE = '1')) ) then State <= ST_WAIT_FOR_SAMP; SPI_Wr_Data_ShiftReg <= SPI_Wr_Data_ShiftReg(14 downto 0) & '0';--//--if 8 bit the output would be from bit 7 end if; When ST_WAIT_FOR_SAMP => CLK_EN_ACTIVE_Trig <= '0'; if( ((CPHA = '0') and ( CLK_RISE= '1')) or ((CPHA = '1') and (CLK_FALL = '1')) ) then State <= ST_WAIT_FOR_LOAD; SPI_Rd_Data_ShiftReg <=SPI_Rd_Data_ShiftReg (14 downto 0) & SPI_MasterIn ; --insted of 0ne would be data. if (ShiftCount = SPI_DATA_LENGTH_DEF)then State <= ST_END_SAMP_REG; else ShiftCount <= ShiftCount + 1; end if; --read data end if; When ST_END_SAMP_REG => CLK_EN_ACTIVE_Trig <= '0'; State <= ST_Idle; SPI_Rd_Data<=SPI_Rd_Data_ShiftReg ;-- update data SPI_Data_Count_reg <= SPI_Data_Count_reg +1; SPI_Wr_DONE <= '1'; end case; end if; end process; end STRUCTURE; Я хочу к нему подключиться и говорить с внешним прибором. Я создал еще один модуль для реализации логики. entity SPI_CAN is port( SPI_CAN_RST :In Std_logic; --Main DSP system reset. SPI_CAN_GCLK :In Std_logic; --DSP MAin Clock to be divided. SPI_CAN_WR_DATA :out Std_logic_vector(15 downto 0); --write data to SPI SPI_CAN_RD_DATA :in Std_logic_vector(15 downto 0); --read data from SPI SPI_CAN_WR_START_TRIG :in Std_logic; SPI_CAN_WR_DONE :out Std_logic; SPI_CAN_WR_DONE_CLEAR :in Std_logic ); end SPI_CAN; И делаю мап между модулями. U_GENERIC_SPI : GENERIC_SPI port map( ------------------------------------------- RST => SPI_CAN_RST, CLK => SPI_CAN_GCLK, SPI_nCS => CAN_CS, SPI_CLK => CAN_CLK, SPI_MasterOut => CAN_SDO, SPI_MasterIn => CAN_SDI, SPI_CTRL_REG => "000", --SPI_CTRL_REG <= "000"; --bit0 = CPHA bit1 = CPOL bit2 = MSBnLSB_FIRST SPI_BAUD_DIV => X"000F", SPI_DATA_LENGTH => '0', --SPI_DATA_LENGTH , 0 = length of 8 bits SPI_Wr_Data => SPI_CAN_WR_DATA, SPI_Rd_Data => SPI_CAN_RD_DATA, SPI_Wr_Start_Trig => SPI_CAN_WR_START_TRIG, SPI_Rd_Start_Trig => '0', --not in use read wsing write SPI_Data_Ready => open, --not in use yet SPI_Data_Ready_Clear => '0', --not in use yet SPI_Wr_DONE => SPI_CAN_WR_DONE, SPI_Wr_DONE_Clear => SPI_CAN_WR_DONE_CLEAR, SPI_WR_En => open, --not in use yet SPI_Data_Count => open ); Получаю ошибку actual port "SPI_CAN_WR_DATA" of mode "out" cannot be associated with formal port "SPI_Wr_Data" of mode "in" В чем криминал? Соединяю выход на вход, все честно. Изменено 5 февраля, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Александр77 1 5 февраля, 2017 Опубликовано 5 февраля, 2017 · Жалоба Вообще странно что Вы соединяете два компонента не используя сигналы. Сделайте например так для каждого соединения: ... architecture ... ... signal SPI_CAN_WR_DATA_s:std_logic_vector(15 downto 0); .... begin COMPONENT1:NAME port map ( ... SPI_Wr_Data => SPI_CAN_WR_DATA_s, ... ); component2:name port map ( ... SPI_CAN_WR_DATA => SPI_CAN_WR_DATA_s, ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 5 февраля, 2017 Опубликовано 5 февраля, 2017 (изменено) · Жалоба Вообще странно что Вы соединяете два компонента не используя сигналы. дело в том что я видел примеры без использования сигналов. поэтому не знал как правильней. и еще что меня сбивает с толку - есть примеры где делают мап вход на вход, выход на выход, а есть где делают выход на вход. а как правильно делать? у меня есть пример. LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY arthur IS PORT( clk : IN STD_LOGIC; --clock input enbl : IN STD_LOGIC; --enable for arthur adv : IN STD_LOGIC; --advance the state pulse : OUT STD_LOGIC; --pulse the dog collar open_door : OUT STD_LOGIC --output to door driver ); END arthur; ARCHITECTURE struct OF arthur IS SIGNAL ask_me : STD_LOGIC; --barney asks elmo SIGNAL clear : STD_LOGIC; --elmo clears request to ask COMPONENT barney PORT(clk : IN STD_LOGIC; enable : IN STD_LOGIC; adv : IN STD_LOGIC; clear : IN STD_LOGIC; outa : OUT STD_LOGIC; ask_me : OUT STD_LOGIC ); END COMPONENT; COMPONENT elmo PORT(ask_me : IN STD_LOGIC; go : OUT STD_LOGIC; clear : OUT STD_LOGIC ); END COMPONENT; BEGIN U1 : barney PORT MAP(clk => clk, enable => enbl, adv => adv, clear => clear, outa => pulse, ask_me => ask_me ); U2 : elmo PORT MAP(ask_me => ask_me, go => open_door, clear => clear ); END struct; как мы видим выход ask_me от barney одключается напрямую ко входу ask_me от elmo. Изменено 5 февраля, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Александр77 1 5 февраля, 2017 Опубликовано 5 февраля, 2017 · Жалоба Для "внутренних" соединений используются сигналы. Если у компонента порт выходит сразу наружу (неважно вход, выход или двунаправленный) то его можно сразу назначать в карте соединений. как мы видим выход ask_me от barney одключается напрямую ко входу ask_me от elmo. А то что этим выходам назначены и одноименные сигналы Вы не наблюдаете? SIGNAL ask_me : STD_LOGIC; --barney asks elmo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 5 февраля, 2017 Опубликовано 5 февраля, 2017 (изменено) · Жалоба Для "внутренних" соединений используются сигналы. Если у компонента порт выходит сразу наружу (неважно вход, выход или двунаправленный) то его можно сразу назначать в карте соединений. А то что этим выходам назначены и одноименные сигналы Вы не наблюдаете? SIGNAL ask_me : STD_LOGIC; --barney asks elmo ах да, точно. вот что меня бесит это когда пины и сигналы имеют одинаковые имена. сиди гадай кто к кому подключен. то есть если я правильно понял то соединение двух компонентов такое? (component 1 ) PIN/PORT OUT -> signal -> PIN/PORT IN (component 2) Изменено 5 февраля, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Александр77 1 5 февраля, 2017 Опубликовано 5 февраля, 2017 · Жалоба ах да, точно. вот что меня бесит это когда пины и сигналы имеют одинаковые имена. сиди гадай кто к кому подключен. Тут конечно можно о стиле долго рассуждать. У себя в проектах всегда добавляю "суффиксы":_v - переменная, _s - сигнал, _с - константа. то есть если я правильно понял то соединение двух компонентов такое? (component 1 ) PIN/PORT OUT -> signal -> PIN/PORT IN (component 2) Да правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 5 февраля, 2017 Опубликовано 5 февраля, 2017 · Жалоба Тут конечно можно о стиле долго рассуждать. У себя в проектах всегда добавляю "суффиксы":_v - переменная, _s - сигнал, _с - константа. Да правильно. спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 февраля, 2017 Опубликовано 6 февраля, 2017 · Жалоба честно говоря я не очень понимаю как использовать SPI модуль. чтоб записать в модуль нужно загрузить данные в регистр записи SPI_Wr_Data и поднять сигнал тригер SPI_Wr_Start_Trig. по сигналу данные уйдут на пине SPI_MasterOut сериально. то есть нужно сделать что то вроде SPI_Wr_Data <= "10010000"; triger <= '1'; SPI_Wr_Start_Trig<= triger ; вопрос когда опустить тригер? или другими словами - как послать несколько байт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Александр77 1 6 февраля, 2017 Опубликовано 6 февраля, 2017 · Жалоба Сделайте конечный автомат, который будет "дергать" нужные выводы Ваших компонентов. Для начала можете задействовать простой счетчик с дешифратором: совпал код - формируем сигнал записи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 февраля, 2017 Опубликовано 6 февраля, 2017 · Жалоба Сделайте конечный автомат, который будет "дергать" нужные выводы Ваших компонентов. Для начала можете задействовать простой счетчик с дешифратором: совпал код - формируем сигнал записи. Я не понимаю когда сигнал записи рисетовать. В каком кейсе автомата. Я не очень искушен в VHDL. Не понимаю еще как правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 6 февраля, 2017 Опубликовано 6 февраля, 2017 · Жалоба Я не понимаю когда сигнал записи рисетовать. В каком кейсе автомата. Я не очень искушен в VHDL. Не понимаю еще как правильно. Могу рассказать "Как"... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Александр77 1 6 февраля, 2017 Опубликовано 6 февраля, 2017 · Жалоба Я не понимаю когда сигнал записи рисетовать. В каком кейсе автомата. Я не очень искушен в VHDL. Не понимаю еще как правильно. Тут многое от построения зависит, но в общих чертах: делаем счетчик от 0 до 15 (или другого значения); пишем "дешифратор" который будет каждое состояние счетчика сравнивать с константами, например счетчик досчитал до 3, проводим действие (установили сигнал), дошел счетчик до 5 - сбросили сигнал. И так далее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 февраля, 2017 Опубликовано 6 февраля, 2017 · Жалоба Могу рассказать "Как"... был бы очень признателен. Тут многое от построения зависит, но в общих чертах: делаем счетчик от 0 до 15 (или другого значения); пишем "дешифратор" который будет каждое состояние счетчика сравнивать с константами, например счетчик досчитал до 3, проводим действие (установили сигнал), дошел счетчик до 5 - сбросили сигнал. И так далее. мне кажется сигнал сброса должен быть синхронизирован с переходом в другой стэйт например с RECEIVE в IDLE. скажем чисто по тупому запись нескольких байт можно было представить так --first byte SPI_Wr_Data <= "00000001"; trigger <= '1'; SPI_Wr_Start_Trig <= trigger; --??? delay? trigger <= '0'; SPI_Wr_Start_Trig <= trigger; --second byte SPI_Wr_Data <= "00000011"; trigger <= '1'; SPI_Wr_Start_Trig <= trigger; trigger <= '0'; SPI_Wr_Start_Trig <= trigger; --and so on... но это конечно не по-vhdl-овски. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Александр77 1 6 февраля, 2017 Опубликовано 6 февраля, 2017 · Жалоба был бы очень признателен. Ну так пообщайтесь в скайпе - Вам уже руку помощи предложили, неужто надо этой рукой Вас за шиворот к монитору притянуть? мне кажется сигнал сброса должен быть синхронизирован с переходом в другой стэйт например с RECEIVE в IDLE. Начинайте осваивать моделсим - попробуете все кажущиеся Вам правильными варианты, или один из них и определитесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 6 февраля, 2017 Опубликовано 6 февраля, 2017 · Жалоба Ну так пообщайтесь в скайпе - Вам уже руку помощи предложили, неужто надо этой рукой Вас за шиворот к монитору притянуть? Начинайте осваивать моделсим - попробуете все кажущиеся Вам правильными варианты, или один из них и определитесь. понял. ModelSim я уже качаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться