Advertisement
Guest User

Untitled

a guest
Jun 3rd, 2016
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module test3(inout sda, input scl);
  2.  
  3. localparam I2C_ADR = 7'h27;
  4.  
  5. reg adr_match;     // флажок совпадения адреса устройства
  6. reg [1:0] phase;   // b10 или b00 - проверка адреса устройства, b01 - запись адреса регистра, b11 - запись значения регистра
  7. reg [7:0] reg_mem; // значение адреса регистра
  8. reg [7:0] val_mem; // значение регистра
  9. reg [3:0] bitcnt;  // счетчик битов
  10. reg start;
  11.  
  12. // устанавливаем start = 1 при обнаружении START последовательности
  13. // другие события устанавливают start = 0
  14. always @(negedge sda or negedge scl) if(~sda) start <= scl; else start <= 0;
  15.  
  16. always @(negedge scl or posedge start)
  17. if(start) begin     // start = 1, сработал триггер posedge start
  18.     bitcnt <= 4'h0; // инициируем счетчик битов
  19.     phase <= 2'b00; // переходим к проверки адреса устройства
  20. end else begin      // start = 0, сработал триггер negedge scl
  21.     if(bitcnt[3]) begin      // считали последний бит
  22.         bitcnt <= 4'h0;      // инициируем счетчик битов
  23.         phase <= (~phase[0]) ? 2'b01 : 2'b11 ; // переходим к записи либо адреса либо значения регистра
  24.     end
  25.      else bitcnt <= bitcnt + 4'h1; // инкрементируем счетчик битов
  26. end
  27.  
  28. always @(posedge scl)
  29. begin
  30.     if(~phase[0]) begin // проверка адреса устройства
  31.         if(bitcnt == 4'h1) adr_match <= (sda == I2C_ADR[6]); // поднимаем флажок если первые биты совпадают
  32.         else if(bitcnt < 4'h8 && sda != I2C_ADR[4'h7 - bitcnt]) adr_match <= 1'b0; // сбрасываем, если хотя бы один не совпал
  33.     end else if(~phase[1] && adr_match) reg_mem[4'h8 - bitcnt] <= sda;  // запись адреса регистра
  34.     else if(adr_match) val_mem[4'h8 - bitcnt] <= sda; // запись значения регистра
  35. end
  36. // переполнение счетчика, считали последний бит
  37. // если адрес устройства совпадает, устанавливаем sda = 0
  38. // иначе устанавливаем sda в режим high impedance
  39. assign sda = (bitcnt[3] && adr_match) ? 1'b0 : 1'bz;
  40.  
  41. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement