VitalyM4 0 2 апреля, 2007 Опубликовано 2 апреля, 2007 · Жалоба Здравствуйте Уважаемые! Подскажите как правильно определять старт - стоп условия в I2C. Я сделал вот так, но носом чую, что где-то лажа :) //------------------------------------------------------------------------------------------------------------------------ // generate shift register always @(posedge SCL) sr <= {sr[6:0],SDA}; assign my_adr = (sr[7:1] == I2C_ADR); //?????????????????????????????????? //generate bit-counter always @(posedge SCL) if(ld) bit_cnt <= 3'b111; else bit_cnt <= bit_cnt - 3'h1; //generate access done signal assign acc_done = !(|bit_cnt); //detect start condition always @(negedge SDA) sta<=SCL; //------------------------------------------------------------------------------------------------------------------- always @(posedge SCL or posedge sto) if(sto) d_sta<=1'b0; else d_sta <= sta; // detect stop condition always @(posedge SDA or posedge sta) if(sta) sto <= 1'b0; else if(SCL) sto <= 1'b1; //generate i2c_reset signal assign i2c_reset = sta || sto; //----------------------------------------------------------------------------------------------------------------------- Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Doka 1 2 апреля, 2007 Опубликовано 2 апреля, 2007 · Жалоба а почему бы не взять готовый XAPP с исходниками на Верилог? (кстати, логики там немного - поскольку писали они под CPLD) или тут посмотрите: http://electronix.ru/forum/index.php?showtopic=9079 http://electronix.ru/forum/index.php?showtopic=16152 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dj_Atmex 0 2 апреля, 2007 Опубликовано 2 апреля, 2007 · Жалоба Ну старт-стоп условия вы првильно определили. А в чем проблема-то конкретно? =) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VitalyM4 0 3 апреля, 2007 Опубликовано 3 апреля, 2007 · Жалоба Ну старт-стоп условия вы првильно определили. А в чем проблема-то конкретно? =) Да делаю асикс, надо i2c/spi слейв сделать, вот я и пытаюсь с минимальными ресурсами это сделать. Нашел на опенкорес модель памяти мне в самый раз и по ресурсам классно, но в ней есть один недостаток она не совсем хорошо синтезится. В частности старт-стоп несинтезился вот я передлал и попросил посмотреть знающих или все ок. Щас посмотрю ХАРР может там меня спасут Вот код кому интересно. reg [7:0] mem [0:15]; // initiate memory //GENERATE!! reg [7:0] mem_adr; // memory address reg [7:0] mem_do; // memory data output // statemachine declaration parameter idle = 3'b000; parameter slave_ack = 3'b001; parameter get_mem_adr = 3'b010; parameter gma_ack = 3'b011; parameter data = 3'b100; parameter data_ack = 3'b101; genvar i; initial begin SDA_o =1; state = idle; end //-------------------------------------------------------------------------------------------------------- assign st_reset=sto || (sta && !d_sta); //------------------------------------------------------------------------------------------------------------------------ // generate shift register always @(posedge SCL) sr <= {sr[6:0],SDA}; assign my_adr = (sr[7:1] == I2C_ADR); //?????????????????????????????????? //generate bit-counter always @(posedge SCL) if(ld) bit_cnt <= 3'b111; else bit_cnt <= bit_cnt - 3'h1; //generate access done signal assign acc_done = !(|bit_cnt); //detect start condition always @(negedge SDA) sta<=SCL; //------------------------------------------------------------------------------------------------------------------- always @(posedge SCL or posedge sto) if(sto) d_sta<=1'b0; else d_sta <= sta; // detect stop condition always @(posedge SDA or posedge sta) if(sta) sto <= 1'b0; else if(SCL) sto <= 1'b1; //generate i2c_reset signal assign i2c_reset = sta || sto; //----------------------------------------------------------------------------------------------------------------------- // generate statemachine always @(negedge SCL or posedge st_reset) if(st_reset ) begin state <= idle; // reset statemachine SDA_o <= 1'b1; ld <= 1'b1; end else begin // initial settings SDA_o <= 1'b1; ld <= 1'b0; case(state) // synopsys full_case parallel_case idle: // idle state if (acc_done && my_adr) begin state <= slave_ack; rw <= sr[0]; SDA_o <= 1'b0; // generate i2c_ack #1; if(rw) begin mem_do <= mem[mem_adr]; end end slave_ack: begin if(rw) begin state <= data; SDA_o <= mem_do[7]; end else state <= get_mem_adr; ld <= 1'b1; end get_mem_adr: // wait for memory address if(acc_done) begin state <= gma_ack; mem_adr <= sr; // store memory address SDA_o <= !(sr <= 15); // generate i2c_ack, for valid address end gma_ack: begin state <= data; ld <= 1'b1; end data: // receive or drive data begin if(rw) SDA_o <= mem_do[7]; if(acc_done) begin state <= data_ack; mem_adr <= mem_adr + 8'h1; SDA_o <= (rw && (mem_adr <= 15) ); // send ack on write, receive ack on read if(rw) mem_do <= mem[mem_adr]; if(!rw) // mem[ mem_adr[3:0] ] <= sr; // store data in memory mem[ mem_adr[3:0] ] <= sr; end if(!acc_done && rw) mem_do <= {mem_do[6:0], 1'b1}; // insert 1'b1 for host ack generation end data_ack: begin ld <= 1'b1; if(rw) if(sr[0]) // read operation && master send NACK begin state <= idle; SDA_o <= 1'b1; end else begin state <= data; SDA_o <= mem_do[7]; end else begin state <= data; SDA_o <= 1'b1; end end endcase end // generate tri-states assign SDA = SDA_o ? 1'bz : 1'b0; assign DATA_OUT=mem[4'd3]; Вот эту стейт машину надо под SPI постраться прикрутить. И чтобы автоинкремент адреса был :maniac: Да может кто-то глянет в state==data я не могу понять в чем проблема, почему когда убераешь #1 перестает читать из памяти??? Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 3 апреля, 2007 Опубликовано 3 апреля, 2007 · Жалоба Что касается старта. Наверно недостаточно одной строчки always @(negedge sda or negedge scl) begin if(scl == 1'b0) start <= 1'b0; else start <= 1'b1; end always @(posedge sda or posedge start) begin if(start) stop <= 1'b0; else if(scl) stop <= 1'b1; end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VitalyM4 0 6 апреля, 2007 Опубликовано 6 апреля, 2007 (изменено) · Жалоба Спасибо!!! Продолжая SPI/I2C эпопею. Запутался совсем. С записью проблем нету ни в SPI ни в I2C режиме, но в режиме чтения появляется 1 лишний бит. Как его убрать?? В SPI режиме 9 бит пустой и нужен только для экономии места, чтобы максимум использовать регистры I2C module i2c_vim (nRESET, SCL ,SDA,SSB,MODE,DATA_OUT); input SCL; wire SCL; input nRESET; inout SDA; input MODE; //1=I2C mode, 0=SPI mode; input SSB; output [7:0] DATA_OUT; //--------------------------------------------------------------------------------------------------- reg [7:0] mem [0:15]; // initiate memory //GENERATE!! reg [7:0] mem_adr; // memory address reg [7:0] mem_do; // memory data output //I2C statemachine declaration parameter idle = 3'b000; parameter slave_ack = 3'b001; parameter get_mem_adr = 3'b010; parameter gma_ack = 3'b011; parameter data = 3'b100; parameter data_ack = 3'b101; //-------------------------------------------------------------------------------------------------------- assign sto=(MODE) ? sto_int: SSB; //------------------------------------------------------------------------------------------------------- assign st_reset=sto || sta || !nRESET; //------------------------------------------------------------------------------------------------------------------------ always @(posedge SCL or posedge st_reset) if(st_reset) sr<=8'b00000000; else sr <= {sr[6:0],SDA}; assign my_adr = (sr[7:1] == I2C_ADR); //generate bit-counter always @(posedge SCL or posedge st_reset) if(st_reset) bit_cnt<=3'b000; else if(ld) //|!!!!!!!!!!! bit_cnt <= 3'b111; else bit_cnt <= bit_cnt - 3'h1; //generate access done signal always@(posedge SCL or posedge st_reset) if(st_reset) acc_done<=1'b1; else if(bit_cnt==3'b001) acc_done<=1'b1; else acc_done<=1'b0; //detect start condition always@(negedge SDA or negedge SCL) if(SCL==1'b0) sta<=1'b0; else sta<=1'b1; // detect stop condition always@(posedge SDA or posedge sta) if(sta) sto_int<=1'b0; else if (SCL) sto_int<=1'b1; //----------------------------------------------------------------------------------------------------------------------- // generate statemachine always @(negedge SCL or posedge st_reset) if (st_reset ) begin if(MODE) begin state <= idle; // reset statemachine in I2C mode SDA_o <= 1'b1; ld <= 1'b1; end else begin state <= get_mem_adr; // reset statemachine in I2C mode SDA_o <= 1'b1; ld <= 1'b1; end end else begin SDA_o<=1'b1; case(state) // synopsys full_case parallel_case idle: // idle state begin ld<=1'b0; if (acc_done && my_adr) begin state <= slave_ack; rw <= sr[0]; SDA_o <= 1'b0; // generate i2c_ack end end slave_ack: begin if(rw) state <= data; else state <= get_mem_adr; ld <= 1'b1; end get_mem_adr: // wait for memory address begin ld<=1'b0; if(acc_done) begin state <= gma_ack; mem_adr <= sr; // store memory address if(MODE) SDA_o <= !(sr <= 15); // generate i2c_ack, for valid address else SDA_o <=1'b1; end end gma_ack: begin state <= data; ld <= 1'b1; mem_do<=mem[mem_adr]; if (!MODE) rw<=SDA; end data: // receive or drive data begin // read data from memory if(!acc_done && rw) begin mem_do <= {mem_do[6:0], 1'b1}; SDA_o <= mem_do[7]; end ld<=1'b0; if(acc_done) begin //--------------------------------------------------------- if(MODE) SDA_o <= (rw && (mem_adr <= 15)); // send ack on write, receive ack on read else SDA_o<=1'b1; //---------------------------------- state <= data_ack; mem_adr<=mem_adr+8'h1; if(!rw) begin mem[ mem_adr[3:0] ] <= sr; end else begin mem_do<=mem[mem_adr]; end end end data_ack: begin ld <= 1'b1; mem_do<=mem[mem_adr]; if(rw) if(sr[0] && MODE) // read operation && master send NACK I2C begin state <= idle; SDA_o <= 1'b1; end else begin state <= data; SDA_o <= mem_do[7]; end else begin state <= data; SDA_o <= 1'b1; end end endcase end // generate tri-states assign SDA = SDA_o ? 1'bz : 1'b0; assign DATA_OUT=mem[4'd3]; pullup(SDA); endmodule На рисунке место с ошибкой там где курсор. Спасибо!! Еще вопросик, что такое Feedback mux ?? Чем это чревато?? Изменено 6 апреля, 2007 пользователем -=Vitaly=- Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться