Перейти к содержанию
    

Двунаправленные сигналы в VERILOG.

Здравствуйте!!

 

Не подскажите как в VERILOGе использовать двунаправленные сигналы, пример такие сигналы как SDA в I2C. А то я совсем запутался.

 

Спасибо!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот простой пример

 

module ap6 (da, db, oe_n, dir);

inout [7:0] da;

inout [7:0] db;

input oe_n;

input dir;

 

 

assign db = (dir & !oe_n) ? da : 8'hzz;

assign da = (!dir & !oe_n) ? db : 8'hzz;

 

endmodule

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

module tristate_buff #(parameter bus_width=16)

_ _ _ _ _ _ (input bit [bus_width-1:0] data_in,

_ _ _ _ _ _ output bit [bus_width-1:0] data_out,

_ _ _ _ _ _ inout wire [bus_width-1:0] DQ,

_ _ _ _ _ _ input bit tristate_n

_ _ _ _ _ _ );

 

_ _ assign DQ=(tristate_n==1'b0)?'z:data_in;

_ _ always_comb data_out=DQ;

 

endmodule

post-5973-1175103684_thumb.jpg

практически то же самое только параметризированной ширины -DQ на пины, все остальные - внутренние cигналы кристалла

(и на всяк случай - если скорости большие вставляйте регистры на входы-выходы кристалла)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не получается сделать inout порт:

 

parameter sdram_addr_bus_wight=11; //Sdram address inputs bus wight

parameter data_wigth_bus=32;

parameter addr_bus_wigth=23;

parameter t_CK=6; //Clock cycle time

parameter t_RCD=15/t_CK; //ACTIVE-to-READ or WRITE delay

parameter t_CAS=3;

 

 

input clk;

output reg [3:0]cmd;

output reg LDQM,UDQM;

output reg [1:0] BA;

output reg [sdram_addr_bus_wight-1:0] A;

inout [data_wigth_bus-1:0] DQ;

output reg rdata_valid;

output reg wdata_req;

output reg disable_executed;

output reg ready;

input read_req;

inout [data_wigth_bus-1:0] rw_data;

input write_req;

input disable_io_req;

input [addr_bus_wigth-1:0] addr;

 

-----------------------------

 

-----------------------------

 

initial

begin

cmd<=4'b0111;

LDQM<=0;

UDQM<=0;

BA<=0;

A<=0;

DQ<=0;//выдаёт ошибку

rdata_valid<=0;

wdata_req<=0;

rw_cycle_hold<=0;

clk_counter<=0;

disable_io_hold<=0;

end

 

 

------------

----------

always @(negedge clk)

begin

 

--------

--------

if (RW)

begin

A[9:0]<=hold_addr[10:0]; //read

A[10]<=1'b1;

cmd<=4'b0101;

end

else

begin

A[9:0]<=hold_addr[10:0]; //write

A[10]<=1'b1;

cmd<=4'b0100;

DQ<=hold_wdata; //выдаёт ошибку

end

end

 

 

Как в данном случае реализовать двунаправленный порт?Вообще не совсем понял как работать с двунаправленными портами?Нужно использовать блок assign обязательно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как в данном случае реализовать двунаправленный порт?Вообще не совсем понял как работать с двунаправленными портами?Нужно использовать блок assign обязательно?

по аналогии с приведёнными выше примерами.

теперь для понимания:

двунапраленный порт сколько источников сигнала должен иметь? ответ: как минимум 2. у переменной может быть только один драйвер(источник сирнала). значит порт inout это не переменная(variable), а цепь(net). подробнее о разнице между данными типами объектов см. ссылки ниже:

http://electronix.ru/forum/index.php?showt...st&p=691934 (+ с десяток постов вперёд по развитию обсуждения)

http://electronix.ru/forum/index.php?showt...mp;hl=data+type

цепь не имеет памяти, значит она не может быть использована в процедурных присваиваниях (always_x, initial, final), т.е. можно только assign.

теперь, чтобы понять как это всё должно описываться, представьте схему 2-направленного порта: у вас есть провод из-вне, который разделяется на 2. один конец "направлен" внутрь(вход для считывания), другой подходит к буфферу, способным переключаться в Z-состояние по управляющему сигналу. это драйвер выходного сигнала. Z сосотяние нужно для того, чтобы во время отведённое для приёма данных драйвер выхода не мешал входящему сигналу.

так вот конструкция assign DQ=(rw)?'z:DATA_OUT; описывает ваш буффер с третьим состоянием. если вы считываете с шины, то вы просто используете DQ как input.

вопросы есть?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет,после такого объяснения их просто не может быть :a14: Спасибо!

Зато у меня появился вопрос :)

С таким двунаправленным портом все понятно,

а вот как, например, с портами типа D+, D- от USB ???

возможно ли обойтись простым решением?

 

к примеру есть некий интерфейс, и в нем есть выход, на него нужно коммутировать либо стандартный RS232, либо USB

в подобном случае я видел применяли внешний аналоговый коммутатор (IDTQS4A101)

Но меня интересует можно ли реализовать это на логике? или все-же проще поставить внешний свитч?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зато у меня появился вопрос :)

С таким двунаправленным портом все понятно,

а вот как, например, с портами типа D+, D- от USB ???

Никак. D+/D- сигналы в большой степени аналоговые. VERILOG с аналогом не работает :unsure:

 

в подобном случае я видел применяли внешний аналоговый коммутатор (IDTQS4A101)
Угу, только так

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а вот как, например, с портами типа D+, D- от USB ???

возможно ли обойтись простым решением?

 

к примеру есть некий интерфейс, и в нем есть выход, на него нужно коммутировать либо стандартный RS232, либо USB

:biggrin:

вы имеете ввиду как описать диф.пару?

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

значит остаётся только описание для цифро-аналогово моделирования. это можно. но вот насчёт "простого решения"... хотя, у каждого собственное видение простоты, так что смотрите сами насколько вам это будет просто:

есть такое расширение стандарта Verilog как Verilog-AMS(analig&mixed-signal extension), тоже нужно сказать полноценный стандарт. так вот это расширение служит как раз для сопряжение цифры с аналогом на Verilog.

вот вам примерчик http://www.designers-guide.org/VerilogAMS/ там как раз в самом низу странички есть модель двунаправленной шины (правда не дифференциальной). можете посмотреть как это делается.

ЗЫ: пример дифференциальной я не буду приводить, т.к. вопрос ваш, надо понимать, был задан из чистого любопытства. если хотите понять принципы миграции из одного домена в другой (там достаточно всё просто), то можно взглянуть на стандарт Verilog-AMS - он такой же приятный для чтения и наглядный как основной стандарт Верилога ( http://verilog.org/verilog-ams/htmlpages/p...S-LRM-2-3-1.pdf ).

 

а по поводу коммутации RS и USB, я, честно говоря, не представляю, в чём там суть, поэтому посоветовать что-либо не могу (подскажите вкраце в чём фишка).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вы имеете ввиду как описать диф.пару?

Там не совсем диф.пара, хотя в некоторых режимах работает как диф.пара.

 

вам для каких целей?

обычный свитч

 

синтез, как вы понимаете, из подобного описания не получится. ну, нельзя же попросить ситезатор, чтобы он вам по предложенному вам описанию запёк из кремния изделие с заданными электрическими параметрами. согласны?

согласен...

 

но вот насчёт "простого решения"... хотя, у каждого собственное видение простоты...

Под простым решением я имел в виду, реализовать по-простому, без реализации всего Serial Interface Engine (SIE).

Сами IO реализовать не сложно,

вот тут даже схема есть

http://www.usbmadesimple.co.uk/ums_3.htm

но вот управление трансмиттером, тут без SIE думаю не обойтись..., но может я чего-то не учел...

А реализовать SIE, это фактически весь USB приемник.

 

т.к. вопрос ваш, надо понимать, был задан из чистого любопытства...

Не совсем из любопытства...

Я только осваиваю программируемую логику, и как то была нужна такая функция, но я не нашел решения...

А тут как раз заговорили про двунаправленные порты...

 

а по поводу коммутации RS и USB, я, честно говоря, не представляю, в чём там суть...

Суть в том, чтобы сократить схему, и не использовать внешний коммутатор...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Там не совсем диф.пара, хотя в некоторых режимах работает как диф.пара.

ага, в курсе

Под простым решением я имел в виду, реализовать по-простому, без реализации всего Serial Interface Engine (SIE).

я не знаю, может и можно. я стек протокола USB до сих пор не курил, поэтому советовать что-то не берусь

Суть в том, чтобы сократить схему, и не использовать внешний коммутатор...

внешний коммутатор лучше использовать, т.к. он обойдётся дешевле ваших затрат человеко-часов(с большой долей уверенности).

советом как реализовывать вашу задачу(ядро-коммутатор) я помоч не могу, т.к. нужно вникать ТЗ (на лету мне не уловить, т.к. задача не шаблонная). если нужны советы, то рекоммендую обратиться в соседний подфорум по IP ядрам на ПЛИС. возможно кто-то найдётся, кто в теме.

удач

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброго времени суток уважаемые форумчане!

Долго не решался написать, потому как вопрос не совсем по теме, но раз уж речь зашла о диффренциальных сигналах, то думаю, можно влезть. Мне надо "подружить" S3E и DDC118. Последняя при питании цифровой части 3,3В имеет диффренциальные сигналы. Тут я не знаю, как правильно их классифицировать, потому как каждый из сигналов пары вполне самостоятелен и является просто инверсией другого. Никаких опорных сигналов нет. Максимальная частота цифрового интерфейса до 10 МГц. Некое количество девайсов я разбил на две группы, поэтому могу читать в два потока, т.е. могу снизить частоту до 2МГц (это вытекает из времени считывания и количества считываемой информации). Вопрос спецам - стоит ли мне заморачиваться с дифф. сигналами, или достаточно использовать просто _p сигналы пар? Не сталкивался с этими типами сигналов, но думаю, придумали их не просто так, а для увеличения помехоустойчивости при увеличении частот. Я б конечно хотел бы заложиться на них, потому как, раз уж есть такая возможность, улучшающая характеристики устройства, то надо её использовать. Проблема встаёт с описанием и симуляцией таких сигналов. Порывшись в документе spartan3e_hdl.pdf обнаружил там буфер ввода для дифф. сигналов ibufds. По аналогии потом попробую сам разобраться с выводом. Нашёл V описание:

Verilog Instantiation Template
// IBUFDS: Differential Input Buffer
// Virtex-4/5, Spartan-3/3E/3A
// Xilinx HDL Libraries Guide, version 11.2
IBUFDS #(
     .CAPACITANCE("DONT_CARE"), // "LOW", "NORMAL", "DONT_CARE" (Virtex-4 only)
     .DIFF_TERM("FALSE"), // Differential Termination (Virtex-4/5, Spartan-3E/3A)
     .IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for
                                           // the buffer: "0"-"12" (Spartan-3E)
                                           // "0"-"16" (Spartan-3A)
     .IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input
                                                // register: "AUTO", "0"-"6" (Spartan-3E)
                                                // "AUTO", "0"-"8" (Spartan-3A)
      .IOSTANDARD("DEFAULT") // Specify the input I/O standard
            )
IBUFDS_inst (
        .O(O), // Buffer output
         .I(I), // Diff_p buffer input (connect directly to top-level port)
         .IB(IB) // Diff_n buffer input (connect directly to top-level port)
           );
// End of IBUFDS_inst instantiation

Что означает символ #? Я так понимал, что это только для симулятора и не синтезируемая инструкция? А как же быть тогда с "DIFF_TERM("FALSE"), // Differential Termination" и ".IOSTANDARD("DEFAULT") // Specify the input I/O standard"? Это же физические, не виртуальные параметры. Хотя, в схеме IOB не нашёл терминаторов, а только подтягивающие резисторы, но в тексте даже есть номинал последовательного резистора - 120 Ом. Как это описание вставить в свой проект (меня смущают скобки) и есть ли специальные правила или рекомендации для описания таких сигналов на V (я имею ввиду напрмер clk_in_p - clk_in_n или data_in_p - data_in_n). Как и куда в этом описании буфера ibufds вставить свои обозначения сигналов и портов.

Может быть так (как обычный буфер и пока без #):

IBUFDS_inst (
        .O(data_out), // Buffer output
         .I(data_in_p), // Diff_p buffer input (connect directly to top-level port)
         .IB(data_in_n) // Diff_n buffer input (connect directly to top-level port)
           );
IBUFDS(data_out, data_in_p, data_in_n)

Ещё вопрос по поводу стандарта IO. Порылся в ds312.pdf, там в разделе I/O Capabilities написано:

Spartan-3E FPGAs support the following single-ended

standards:

• 3.3V low-voltage TTL (LVTTL)

• Low-voltage CMOS (LVCMOS) at 3.3V, 2.5V, 1.8V,

1.5V, or 1.2V

• 3V PCI at 33 MHz, and in some devices, 66 MHz

• HSTL I and III at 1.8V, commonly used in memory

applications

• SSTL I at 1.8V and 2.5V, commonly used for memory

applications

Spartan-3E FPGAs support the following differential standards:

• LVDS

• Bus LVDS

• mini-LVDS

• RSDS

• Differential HSTL (1.8V, Types I and III)

• Differential SSTL (2.5V and 1.8V, Type I)

• 2.5V LVPECL inputs

В описании везде фигурирует LVDS_25 и в таблице "Table 10-21: Spartan-3E Differential IOSTANDARD Bank Compatibility" из ug.331.pdf написано, что при VCCO=3,3V при LVDS_25 будет только "Input". Это что такое? При этом питании можно только на вход работать что ли? А если выход, что будет? Ошибка синтеза, выход не 2,5, а 3,3 В или ещё какая напасть?

В описании DDC118 не указано, какой там она стандарт поддерживает LVTTL или LVCMOS, а про дифф. сигналы вообще ничего нет. Как в таких случаях быть - поставить для дифф. - LVDS, а для одиночных сигналов LVTTL? Пытался слить jesd8c, не дают. Пока не знаю, как быть. Конечно методом тыка как то и заработает может быть, но хотелось бы сделать правильно, как надо!

И как быть с симуляцией? Вообщем, если кто чем может помочь, заранее спасибо!

Изменено пользователем at89c51ed2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 CaPpuCcino

Не буду с Вами спорить, согласен с этими доводами. Сделаю новую тему. Только, мне пока не понятно, почему раздел то другой? Я ж испытываю трудности с описанием в V. Трудности с IOB это можно в тот раздел, но тут вопрос то был взаимосвязанный! Как решим куда перенести тему, не вопрос перенесу без проблем! Тогда вопрос сюда по теме. Нужна мне bidir шина для связи с процом 8 битная. Порывшись там же - spartan3e_hdl.pdf, нашёл соответствующий буфер iobuf. Описание такое:

Verilog Instantiation Template
// IOBUF: Single-ended Bi-directional Buffer
// All devices
// Xilinx HDL Libraries Guide, version 11.2
IOBUF #(
.DRIVE(12), // Specify the output drive strength
.IBUF_DELAY_VALUE("0"), // Specify the amount of added input delay for the buffer,
// "0"-"12" (Spartan-3E only), "0"-"16" (Spartan-3A only)
.IFD_DELAY_VALUE("AUTO"), // Specify the amount of added delay for input register,
// "AUTO", "0"-"6" (Spartan-3E only), "0"-"8" (Spartan-3A only)
("DEFAULT"), // Specify the I/O standard
.SLEW("SLOW") // Specify the output slew rate
) IOBUF_inst (
.O(O), // Buffer output
.IO(IO), // Buffer inout port (connect directly to top-level port)
.I(I), // Buffer input
.T(T) // 3-state enable input, high=input, low=output
);
// End of IOBUF_inst instantiation

Вопрос - в чём измеряются задержки .IBUF_DELAY_VALUE("0") и .IFD_DELAY_VALUE("AUTO"). Видел их в IOB и читал, что нужны для DCM и выравнивания задержек по плате. Думаю, мне можно всё поставить "по умолчанию". Вообщем вместо кучи вопросов приведу код, как я это думаю описать, а люди знающие (если захотят помочь) скажут, где ошибка.

IOBUF #(
.DRIVE(12), // поставил по умолчанию 12 мА
.IBUF_DELAY_VALUE("0"), // Поставил без задержки
.IFD_DELAY_VALUE("AUTO"), // Поставил "по умолчанию"
.IOSTANDARD("LVTTL"), //Не знаю как надо, выход на проц с питанием 3,3В
.SLEW("SLOW") //Не знаю, сейчас медленно-нарастающие фронты
) IOBUF_inst (
.O(Bus_In[7:0]), //Выход буфера, т.е. то, что считано с выводов ФПГА и пойдёт внуть ФПГА
.IO(BiDir_Bus[7:0]), //Собственно сама двунаправленная шина, пины ФПГА
.I(Bus_Out[7:0]), //Вход буфера, т.е. то, что надо выдать на выход ФПГА изнутри ФПГА
.T(Read_Bus) //Чтение шины по 1, вывод на шину по 0
);

Как в top-levele описать BiDir_Bus[7:0]? Есть input, output, а как описать bidir? Про симуляцию пока уж молчу, потом, как компиляция пройдёт видно будет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все на самом деле очень просто. Непонятно что тут раздули такие обсуждения. Вот пример описания двунаправленного сигнала в верилоге, который в результате мэппинга размещается в IOB.

module test(

inout my_sig,

input oe

);

 

wire input_from_IOB = my_sig; // это вход

assign my_sig = (oe)? 'b1: 'bz; // драйвим выход когда oe в 1

 

endmodule

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Решил не плодить темы и добавлю сюда вопрос.

 

Есть flash 512 mbit.

Хочу к ней написать модуль для чтения и записи, а затем прикрутить к шине Avalon на Nios II.

Пока пробую сделать процедуру чтения без привязки к nios.

 

Само чтение делаю как автомат состояний, потому что сигналы по разному во времени выставляются.

Есть двунаправленная шина data_f, которая считывает данные при чтении и выставляет при записи.

 

пытаюсь промоделировать все это дело в квартусе и получаю, что данные ни разу не считываются с data_f при чтении и не записываются в data_out_nii.

Причем, если сделать из inout просто output и убрать assign, то все прекрасно работает.

 

Понимаю, что ошибка где-то с inout с его использованием, также не ясна работа с условием в assign:

post-44580-1269801932_thumb.jpg

post-44580-1269802714_thumb.jpg

module Flash512Mbit (clk,reset_n,cs,wr_en,rd_en,address_nii,data_in_nii,data_out_nii,cur_state,ce
_n,we_n,oe_n,address_f,data_f);

input wire clk;
input wire reset_n;
input wire cs;
input wire wr_en;
input wire rd_en;
input wire [25:0] address_nii;
input wire [15:0] data_in_nii;
output reg [15:0] data_out_nii;
output reg [3:0] cur_state;

output reg ce_n;
output reg we_n;
output reg oe_n;

output reg [25:0] address_f;
inout wire [15:0] data_f;

// local variables
reg [15:0] data_in;
reg [3:0] OE_cnt;
reg SetAddr_cnt;
reg WE_cnt;

parameter         Reset_st = 0, Main_st = 8,
/*read states*/        WE_p = 1, SetAddr = 2,     CE_a = 3, OE_a = 4, 
                    DataRd = 5,    OE_CE_p = 6, WE_a = 7;

reg [3:0] state;

assign data_f = (cs && wr_en)? data_in_nii : 16'bZ;

always @(state) begin
        case (state)
            Reset_st:                            
                cur_state <= 0;                
                
            Main_st:                
                cur_state <= 8;
                
            ... ... ... ... ...
            WE_a:
                cur_state <= 7;    
                
            default:
                cur_state <= 15;
        endcase
    end

// Determine the next state
always @(posedge clk) begin
    if (!reset_n)
    begin
        ce_n     <= 1;
        we_n     <= 1;
        oe_n     <= 1;
        address_f <= 0;
        OE_cnt <= 0;
        SetAddr_cnt <= 0;
        WE_cnt <= 0;
        state <= Reset_st;        
    end

    else
        case (state)
            Reset_st:
                state <= Main_st;
                
            Main_st:
            begin
                if (cs && rd_en)
                    state <= WE_p;
                else
                    state <= Main_st;                
            end
                    
            SetAddr:
            begin
                address_f <= address_nii;
                if (SetAddr_cnt == 1)
                begin
                    SetAddr_cnt <= 0;
                    state <= CE_a;
                end
                else
                begin
                    SetAddr_cnt <= SetAddr_cnt + 1;
                    state <= SetAddr;                
                end
            end
                    
            ... ... ...    
                    
            DataRd:
            begin
                data_out_nii <= data_f;
                state     <= OE_CE_p;                    
            end
                
            ... ... ... 
                
            default:
                state <= Reset_st;        
        endcase
end

endmodule

 

Вопросы:

1. почему при cs=1 && wr_en=1 активно 3-е состояние - 16'bZ.

по логике: (a=1) ? true : false

2. почему данные с data_f = 0123 не передаются на выходную шину data_out_nii, а появляется какая-то С480?

или моделировать в квартусе двунаправленную шину и выставлять на ней данные для чтения некорректно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...