Browse Source

i2c slave

master
Ivan Olenichev 3 years ago
parent
commit
70c746113a
  1. 176
      i2c_slave/test_i2c_slave/i2c_slave.v
  2. 24636
      i2c_slave/test_i2c_slave/out.vcd
  3. 631
      i2c_slave/test_i2c_slave/qqq
  4. 8
      i2c_slave/test_i2c_slave/readme.txt
  5. 155
      i2c_slave/test_i2c_slave/test_i2c_slave_rx.v
  6. 155
      i2c_slave/test_i2c_slave/test_i2c_slave_tx.v

176
i2c_slave/test_i2c_slave/i2c_slave.v

@ -0,0 +1,176 @@
module i2c_slave (input CLK,
input SCL, /*inout SDA,*/SDA_IN, output SDA_OUT, // FOR TEST
output IS_TRANSMISSION, output IS_READ, output IS_ACK, output WR, //output ACK_MASTER_CTRL,
output /*reg*/ [7:0] RECEIVED_BYTE, input [7:0] BYTE_TO_TRANSMIT,
output [(MAX_I2C_TRANSACTION_EXP2-1):0] COUNTER);
// ALL OPERATIONS WITH MEMORY ARE IN POSEDGE CLK, IN NEGEDGE - ONLY SCL AND SDA LATCH
// COUNTER = 0 - ADRESS RECEIVED, COUNTER >=1 - DATA TRANSMISSION
// RECEIVED BYTES MUST READ WHEN WR POSEDGE, ADRESS NOT READING ###AND BYTE COUNTER >=1 (BYTE COUNTER = 0 - ADRESS)
// BYTES TO TRANSMIT MUST WRITE WHEN WR POSEDGE, BYTE COUNTER CAN BE ZERO
// (FIRST BYTE TRANSMITTED AFTER ADRESS).
// LAST BYTE HAS NO WR ####BUT LAST BYTE NOT TRANSMITTED (DECAUSE MASTER STOPS TRANSMIT)
parameter I2C_ADRESS = 7'h34;
parameter MAX_I2C_TRANSACTION_EXP2 = 9; // !!! - FOR LIMIT BYTES TO TX/RX (WITH ADRESS)
reg /*SDA_IN,*/ SDA_DIR;//, SDA_OUT; // DELETED FOR TEST
initial begin
//SDA_OUT = 0; // DELETED FOR TEST
SCLD = 1;
SDAD = 1;
end
reg SCLD, SDAD;
reg SCL_LAST, SDA_LAST;
reg i2c_state_machine;
initial begin
SCL_LAST = 1; SDA_LAST = 1; i2c_state_machine = 0;
end
reg is_read;
reg [3:0] i2c_bit_counter;
reg [7:0] received_byte;
reg [7:0] byte_to_transmit;
reg [(MAX_I2C_TRANSACTION_EXP2-1):0] byte_counter;
//reg is_for_me;
reg is_ack;
reg wr;//reg ack_master_ctrl;
// FILTER
reg SCLF, SDAF;
reg [3:0] scl_cnt, sda_cnt;
always@(negedge CLK) begin
SCLF = SCL;
SDAF = SDA_IN;
end
always@(posedge CLK) begin
if (scl_cnt != 0) begin
scl_cnt = scl_cnt - 1;
if (scl_cnt == 0) begin
if (SCLD != SCLF)
SCLD = SCLF;
end
end
else begin
if (SCLD != SCLF)
scl_cnt = 3'd7;
end
if (sda_cnt != 0) begin
sda_cnt = sda_cnt - 1;
if (sda_cnt == 0) begin
if (SDAD != SDAF)
SDAD = SDAF;
end
end
else begin
if (SDAD != SDAF)
sda_cnt = 3'd7;
end
// END OF FILTER
//SDA_IN = SDA; // FOR IVERILOG
if ((SDAD == 0) && (SDA_LAST == 1) && (SCLD == 1)) begin
i2c_state_machine = 1;
i2c_bit_counter = 4'd8;
byte_counter = 9'd0;
is_read = 0;
//is_for_me = 1; // RESETS TO ZERO WHEN ADRESS CHECKING
SDA_DIR = 0;
is_ack = 0;
//ack_master_ctrl = 1;
wr = 0;
end
if ((SDAD == 1) && (SDA_LAST == 0) && (SCLD == 1)) begin
i2c_state_machine = 0;
SDA_DIR = 0;
wr = 0;
end
if (i2c_state_machine/* && is_for_me*/) begin
if (!is_read) begin
if (i2c_bit_counter > 0) begin
if ((SCL_LAST == 0) && (SCLD == 1)) begin
received_byte[i2c_bit_counter-1] = SDAD;
i2c_bit_counter = i2c_bit_counter - 1;
end
end
else begin
if ((SCL_LAST == 1) && (SCLD == 0) && (is_ack == 0)) begin
if (byte_counter == 0) begin
if (received_byte[7:1] != I2C_ADRESS)
i2c_state_machine = 0; //is_for_me = 0;
is_read = received_byte[0];
end
else begin
// EMIT SIGNAL OF BYTE RECEIVING
end
if (byte_counter != (2^MAX_I2C_TRANSACTION_EXP2 - 1))
byte_counter = byte_counter + 1;
SDA_DIR = i2c_state_machine; //is_for_me;
is_ack = i2c_state_machine; //1;
//if (is_read) begin
// i2c_bit_counter = 8;
//end
end
else if ((SCL_LAST == 0) && (SCLD == 1) && (is_ack == 1) && (byte_counter > 1))
wr = 1;
else if ((SCL_LAST == 1) && (SCLD == 0) && (is_ack == 1)) begin
is_ack = 0;
SDA_DIR = 0;
i2c_bit_counter = 4'd8;
wr = 0;
end
end
end
else begin // IS_READ
if (i2c_bit_counter > 0) begin
if ((SCL_LAST == 1) && (SCLD == 0)) begin
wr = 0;
SDA_DIR = (BYTE_TO_TRANSMIT[i2c_bit_counter-1] ^ 1) /*& is_for_me & ack_master_ctrl*/;
i2c_bit_counter = i2c_bit_counter - 1;
is_ack = 0;
end
end
else begin
if ((SCL_LAST == 1) && (SCLD == 0) && (is_ack == 0)) begin
SDA_DIR = 0;
is_ack = 1;
end
else if ((SCL_LAST == 0) && (SCLD == 1) && (is_ack == 1)) begin
i2c_bit_counter = 8;
i2c_state_machine = (SDAD ^ 1) | SDA_DIR; //ack_master_ctrl = SDAD+1; // MAYBE TRANSMIT BYTE REPEAT
wr = (SDAD ^ 1) | SDA_DIR;
if (byte_counter != (2^MAX_I2C_TRANSACTION_EXP2 - 1))
byte_counter = byte_counter + 1;
// EMIT SIGNAL OF BYTE TO TRANSMIT
end
end
end
end
SCL_LAST <= SCLD;
SDA_LAST <= SDAD;
//SDA_OUT = (SDA_DIR ^ 1) & SDA; // FOR IVERILOG
end
assign IS_TRANSMISSION = i2c_state_machine;
//assign SDA = SDA_DIR ? 1'b0 : 1'bz;
assign IS_ACK = is_ack;
assign IS_READ = is_read;
assign WR = wr;//assign ACK_MASTER_CTRL = ack_master_ctrl;
assign RECEIVED_BYTE = received_byte;
//assign BYTE_TO_TRANSMIT = byte_to_transmit;
assign COUNTER = byte_counter;
assign SDA_OUT = SDA_DIR ^ 1;
/* SB_IO #(
.PIN_TYPE(6'b 1010_01),
.PULLUP(1'b 0)
) led_io (
.PACKAGE_PIN(SDA),
.OUTPUT_ENABLE(SDA_DIR),
.D_OUT_0(SDA_OUT),
.D_IN_0(SDA_IN)
); */ // DELETED FOR TEST
endmodule

24636
i2c_slave/test_i2c_slave/out.vcd

File diff suppressed because it is too large

631
i2c_slave/test_i2c_slave/qqq

@ -0,0 +1,631 @@
#! /usr/local/bin/vvp
:ivl_version "10.1 (stable)" "(v10_1-109-g5474f9d)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision + 0;
:vpi_module "system";
:vpi_module "vhdl_sys";
:vpi_module "v2005_math";
:vpi_module "va_math";
S_0x14ddf70 .scope module, "test_counter" "test_counter" 2 1;
.timescale 0 0;
P_0x14e9670 .param/l "SCL_H" 0 2 44, +C4<00000000000000000000000001100100>;
P_0x14e96b0 .param/l "SCL_L1" 0 2 45, +C4<00000000000000000000000001000110>;
P_0x14e96f0 .param/l "SCL_L2" 0 2 46, +C4<00000000000000000000000000011110>;
P_0x14e9730 .param/l "SDA_STT" 0 2 43, +C4<00000000000000000000000000011110>;
L_0x152ac00 .functor BUFZ 8, v0x152a370_0, C4<00000000>, C4<00000000>, C4<00000000>;
v0x1529820_0 .net "ACK", 0 0, L_0x152a480; 1 drivers
v0x15298e0_0 .net "I2C_ACTIVITY", 0 0, L_0x152a410; 1 drivers
v0x15299b0_0 .net "I2C_READ", 0 0, L_0x152a540; 1 drivers
v0x1529ab0_0 .var "SCL", 0 0;
v0x1529b80_0 .var "SDA", 0 0;
v0x1529c20_0 .net "SDA_OUT", 0 0, L_0x152aac0; 1 drivers
v0x1529cf0_0 .net "WR", 0 0, L_0x152a600; 1 drivers
v0x1529dc0_0 .net "byte_to_transmit", 7 0, L_0x152ac00; 1 drivers
v0x1529e90_0 .var "clk", 0 0;
v0x1529ff0 .array "data_to", 0 4, 8 0;
v0x152a090_0 .var "i", 8 0;
v0x152a130_0 .net "i2c_counter", 8 0, L_0x152a7b0; 1 drivers
v0x152a200_0 .var "j", 8 0;
v0x152a2a0_0 .net "received_byte", 7 0, L_0x152a6f0; 1 drivers
v0x152a370_0 .var "to_tx", 7 0;
S_0x14ddb90 .scope module, "i2c" "i2c_slave" 2 15, 3 1 0, S_0x14ddf70;
.timescale 0 0;
.port_info 0 /INPUT 1 "CLK"
.port_info 1 /INPUT 1 "SCL"
.port_info 2 /INPUT 1 "SDA_IN"
.port_info 3 /OUTPUT 1 "SDA_OUT"
.port_info 4 /OUTPUT 1 "IS_TRANSMISSION"
.port_info 5 /OUTPUT 1 "IS_READ"
.port_info 6 /OUTPUT 1 "IS_ACK"
.port_info 7 /OUTPUT 1 "WR"
.port_info 8 /OUTPUT 8 "RECEIVED_BYTE"
.port_info 9 /INPUT 8 "BYTE_TO_TRANSMIT"
.port_info 10 /OUTPUT 9 "COUNTER"
P_0x1503870 .param/l "I2C_ADRESS" 0 3 13, C4<0110100>;
P_0x15038b0 .param/l "MAX_I2C_TRANSACTION_EXP2" 0 3 14, +C4<00000000000000000000000000001001>;
L_0x152a410 .functor BUFZ 1, v0x15290c0_0, C4<0>, C4<0>, C4<0>;
L_0x152a480 .functor BUFZ 1, v0x1529180_0, C4<0>, C4<0>, C4<0>;
L_0x152a540 .functor BUFZ 1, v0x1529240_0, C4<0>, C4<0>, C4<0>;
L_0x152a600 .functor BUFZ 1, v0x15295a0_0, C4<0>, C4<0>, C4<0>;
L_0x152a6f0 .functor BUFZ 8, v0x1529300_0, C4<00000000>, C4<00000000>, C4<00000000>;
L_0x152a7b0 .functor BUFZ 9, v0x1528f00_0, C4<000000000>, C4<000000000>, C4<000000000>;
L_0x7faeab837060 .functor BUFT 1, C4<01>, C4<0>, C4<0>, C4<0>;
L_0x152a980 .functor XOR 2, L_0x152a8b0, L_0x7faeab837060, C4<00>, C4<00>;
v0x14de350_0 .net "BYTE_TO_TRANSMIT", 7 0, L_0x152ac00; alias, 1 drivers
v0x1527d00_0 .net "CLK", 0 0, v0x1529e90_0; 1 drivers
v0x1527dc0_0 .net "COUNTER", 8 0, L_0x152a7b0; alias, 1 drivers
v0x1527eb0_0 .net "IS_ACK", 0 0, L_0x152a480; alias, 1 drivers
v0x1527f70_0 .net "IS_READ", 0 0, L_0x152a540; alias, 1 drivers
v0x1528080_0 .net "IS_TRANSMISSION", 0 0, L_0x152a410; alias, 1 drivers
v0x1528140_0 .net "RECEIVED_BYTE", 7 0, L_0x152a6f0; alias, 1 drivers
v0x1528220_0 .net "SCL", 0 0, v0x1529ab0_0; 1 drivers
v0x15282e0_0 .var "SCLD", 0 0;
v0x1528430_0 .var "SCLF", 0 0;
v0x15284f0_0 .var "SCL_LAST", 0 0;
v0x15285b0_0 .var "SDAD", 0 0;
v0x1528670_0 .var "SDAF", 0 0;
v0x1528730_0 .var "SDA_DIR", 0 0;
v0x15287f0_0 .net "SDA_IN", 0 0, v0x1529b80_0; 1 drivers
v0x15288b0_0 .var "SDA_LAST", 0 0;
v0x1528970_0 .net "SDA_OUT", 0 0, L_0x152aac0; alias, 1 drivers
v0x1528b20_0 .net "WR", 0 0, L_0x152a600; alias, 1 drivers
v0x1528bc0_0 .net *"_s12", 1 0, L_0x152a8b0; 1 drivers
L_0x7faeab837018 .functor BUFT 1, C4<0>, C4<0>, C4<0>, C4<0>;
v0x1528c60_0 .net *"_s15", 0 0, L_0x7faeab837018; 1 drivers
v0x1528d40_0 .net/2u *"_s16", 1 0, L_0x7faeab837060; 1 drivers
v0x1528e20_0 .net *"_s18", 1 0, L_0x152a980; 1 drivers
v0x1528f00_0 .var "byte_counter", 8 0;
v0x1528fe0_0 .var "i2c_bit_counter", 3 0;
v0x15290c0_0 .var "i2c_state_machine", 0 0;
v0x1529180_0 .var "is_ack", 0 0;
v0x1529240_0 .var "is_read", 0 0;
v0x1529300_0 .var "received_byte", 7 0;
v0x15293e0_0 .var "scl_cnt", 3 0;
v0x15294c0_0 .var "sda_cnt", 3 0;
v0x15295a0_0 .var "wr", 0 0;
E_0x14ddd50 .event posedge, v0x1527d00_0;
E_0x14dd970 .event negedge, v0x1527d00_0;
L_0x152a8b0 .concat [ 1 1 0 0], v0x1528730_0, L_0x7faeab837018;
L_0x152aac0 .part L_0x152a980, 0, 1;
.scope S_0x14ddb90;
T_0 ;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x15282e0_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x15285b0_0, 0, 1;
%end;
.thread T_0;
.scope S_0x14ddb90;
T_1 ;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x15284f0_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x15288b0_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x15290c0_0, 0, 1;
%end;
.thread T_1;
.scope S_0x14ddb90;
T_2 ;
%wait E_0x14dd970;
%load/vec4 v0x1528220_0;
%store/vec4 v0x1528430_0, 0, 1;
%load/vec4 v0x15287f0_0;
%store/vec4 v0x1528670_0, 0, 1;
%jmp T_2;
.thread T_2;
.scope S_0x14ddb90;
T_3 ;
%wait E_0x14ddd50;
%load/vec4 v0x15293e0_0;
%pad/u 32;
%cmpi/ne 0, 0, 32;
%jmp/0xz T_3.0, 4;
%load/vec4 v0x15293e0_0;
%subi 1, 0, 4;
%store/vec4 v0x15293e0_0, 0, 4;
%load/vec4 v0x15293e0_0;
%pad/u 32;
%cmpi/e 0, 0, 32;
%jmp/0xz T_3.2, 4;
%load/vec4 v0x15282e0_0;
%load/vec4 v0x1528430_0;
%cmp/ne;
%jmp/0xz T_3.4, 4;
%load/vec4 v0x1528430_0;
%store/vec4 v0x15282e0_0, 0, 1;
T_3.4 ;
T_3.2 ;
%jmp T_3.1;
T_3.0 ;
%load/vec4 v0x15282e0_0;
%load/vec4 v0x1528430_0;
%cmp/ne;
%jmp/0xz T_3.6, 4;
%pushi/vec4 7, 0, 4;
%store/vec4 v0x15293e0_0, 0, 4;
T_3.6 ;
T_3.1 ;
%load/vec4 v0x15294c0_0;
%pad/u 32;
%cmpi/ne 0, 0, 32;
%jmp/0xz T_3.8, 4;
%load/vec4 v0x15294c0_0;
%subi 1, 0, 4;
%store/vec4 v0x15294c0_0, 0, 4;
%load/vec4 v0x15294c0_0;
%pad/u 32;
%cmpi/e 0, 0, 32;
%jmp/0xz T_3.10, 4;
%load/vec4 v0x15285b0_0;
%load/vec4 v0x1528670_0;
%cmp/ne;
%jmp/0xz T_3.12, 4;
%load/vec4 v0x1528670_0;
%store/vec4 v0x15285b0_0, 0, 1;
T_3.12 ;
T_3.10 ;
%jmp T_3.9;
T_3.8 ;
%load/vec4 v0x15285b0_0;
%load/vec4 v0x1528670_0;
%cmp/ne;
%jmp/0xz T_3.14, 4;
%pushi/vec4 7, 0, 4;
%store/vec4 v0x15294c0_0, 0, 4;
T_3.14 ;
T_3.9 ;
%load/vec4 v0x15285b0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15288b0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.16, 8;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x15290c0_0, 0, 1;
%pushi/vec4 8, 0, 4;
%store/vec4 v0x1528fe0_0, 0, 4;
%pushi/vec4 0, 0, 9;
%store/vec4 v0x1528f00_0, 0, 9;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529240_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1528730_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529180_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x15295a0_0, 0, 1;
T_3.16 ;
%load/vec4 v0x15285b0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15288b0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.18, 8;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x15290c0_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1528730_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x15295a0_0, 0, 1;
T_3.18 ;
%load/vec4 v0x15290c0_0;
%flag_set/vec4 8;
%jmp/0xz T_3.20, 8;
%load/vec4 v0x1529240_0;
%nor/r;
%flag_set/vec4 8;
%jmp/0xz T_3.22, 8;
%pushi/vec4 0, 0, 32;
%load/vec4 v0x1528fe0_0;
%pad/u 32;
%cmp/u;
%jmp/0xz T_3.24, 5;
%load/vec4 v0x15284f0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.26, 8;
%load/vec4 v0x15285b0_0;
%load/vec4 v0x1528fe0_0;
%pad/u 32;
%subi 1, 0, 32;
%ix/vec4 4;
%store/vec4 v0x1529300_0, 4, 1;
%load/vec4 v0x1528fe0_0;
%subi 1, 0, 4;
%store/vec4 v0x1528fe0_0, 0, 4;
T_3.26 ;
%jmp T_3.25;
T_3.24 ;
%load/vec4 v0x15284f0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%load/vec4 v0x1529180_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.28, 8;
%load/vec4 v0x1528f00_0;
%pad/u 32;
%cmpi/e 0, 0, 32;
%jmp/0xz T_3.30, 4;
%load/vec4 v0x1529300_0;
%parti/s 7, 1, 2;
%cmpi/ne 52, 0, 7;
%jmp/0xz T_3.32, 4;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x15290c0_0, 0, 1;
T_3.32 ;
%load/vec4 v0x1529300_0;
%parti/s 1, 0, 2;
%store/vec4 v0x1529240_0, 0, 1;
T_3.30 ;
%load/vec4 v0x1528f00_0;
%pad/u 32;
%cmpi/ne 10, 0, 32;
%jmp/0xz T_3.34, 4;
%load/vec4 v0x1528f00_0;
%addi 1, 0, 9;
%store/vec4 v0x1528f00_0, 0, 9;
T_3.34 ;
%load/vec4 v0x15290c0_0;
%store/vec4 v0x1528730_0, 0, 1;
%load/vec4 v0x15290c0_0;
%store/vec4 v0x1529180_0, 0, 1;
%jmp T_3.29;
T_3.28 ;
%load/vec4 v0x15284f0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%load/vec4 v0x1529180_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%pushi/vec4 1, 0, 32;
%load/vec4 v0x1528f00_0;
%pad/u 32;
%cmp/u;
%flag_get/vec4 5;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.36, 8;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x15295a0_0, 0, 1;
%jmp T_3.37;
T_3.36 ;
%load/vec4 v0x15284f0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%load/vec4 v0x1529180_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.38, 8;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529180_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1528730_0, 0, 1;
%pushi/vec4 8, 0, 4;
%store/vec4 v0x1528fe0_0, 0, 4;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x15295a0_0, 0, 1;
T_3.38 ;
T_3.37 ;
T_3.29 ;
T_3.25 ;
%jmp T_3.23;
T_3.22 ;
%pushi/vec4 0, 0, 32;
%load/vec4 v0x1528fe0_0;
%pad/u 32;
%cmp/u;
%jmp/0xz T_3.40, 5;
%load/vec4 v0x15284f0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.42, 8;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x15295a0_0, 0, 1;
%load/vec4 v0x14de350_0;
%load/vec4 v0x1528fe0_0;
%pad/u 32;
%subi 1, 0, 32;
%part/u 1;
%pad/u 2;
%pushi/vec4 1, 0, 2;
%xor;
%pad/u 1;
%store/vec4 v0x1528730_0, 0, 1;
%load/vec4 v0x1528fe0_0;
%subi 1, 0, 4;
%store/vec4 v0x1528fe0_0, 0, 4;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529180_0, 0, 1;
T_3.42 ;
%jmp T_3.41;
T_3.40 ;
%load/vec4 v0x15284f0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%load/vec4 v0x1529180_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.44, 8;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1528730_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x1529180_0, 0, 1;
%jmp T_3.45;
T_3.44 ;
%load/vec4 v0x15284f0_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%load/vec4 v0x15282e0_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%load/vec4 v0x1529180_0;
%pad/u 32;
%pushi/vec4 1, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_3.46, 8;
%pushi/vec4 8, 0, 4;
%store/vec4 v0x1528fe0_0, 0, 4;
%load/vec4 v0x15285b0_0;
%pad/u 2;
%pushi/vec4 1, 0, 2;
%xor;
%load/vec4 v0x1528730_0;
%pad/u 2;
%or;
%pad/u 1;
%store/vec4 v0x15290c0_0, 0, 1;
%load/vec4 v0x15285b0_0;
%pad/u 2;
%pushi/vec4 1, 0, 2;
%xor;
%load/vec4 v0x1528730_0;
%pad/u 2;
%or;
%pad/u 1;
%store/vec4 v0x15295a0_0, 0, 1;
%load/vec4 v0x1528f00_0;
%pad/u 32;
%cmpi/ne 10, 0, 32;
%jmp/0xz T_3.48, 4;
%load/vec4 v0x1528f00_0;
%addi 1, 0, 9;
%store/vec4 v0x1528f00_0, 0, 9;
T_3.48 ;
T_3.46 ;
T_3.45 ;
T_3.41 ;
T_3.23 ;
T_3.20 ;
%load/vec4 v0x15282e0_0;
%assign/vec4 v0x15284f0_0, 0;
%load/vec4 v0x15285b0_0;
%assign/vec4 v0x15288b0_0, 0;
%jmp T_3;
.thread T_3;
.scope S_0x14ddf70;
T_4 ;
%pushi/vec4 197, 0, 8;
%store/vec4 v0x152a370_0, 0, 8;
%end;
.thread T_4;
.scope S_0x14ddf70;
T_5 ;
%delay 1, 0;
%load/vec4 v0x1529e90_0;
%inv;
%store/vec4 v0x1529e90_0, 0, 1;
%pushi/vec4 208, 0, 9;
%ix/load 4, 0, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x1529ff0, 4, 0;
%pushi/vec4 0, 0, 9;
%ix/load 4, 1, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x1529ff0, 4, 0;
%pushi/vec4 70, 0, 9;
%ix/load 4, 2, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x1529ff0, 4, 0;
%pushi/vec4 16, 0, 9;
%ix/load 4, 3, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x1529ff0, 4, 0;
%pushi/vec4 152, 0, 9;
%ix/load 4, 4, 0;
%flag_set/imm 4, 0;
%store/vec4a v0x1529ff0, 4, 0;
%jmp T_5;
.thread T_5;
.scope S_0x14ddf70;
T_6 ;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529e90_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x1529ab0_0, 0, 1;
%pushi/vec4 197, 0, 8;
%store/vec4 v0x152a370_0, 0, 8;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x1529b80_0, 0, 1;
%delay 500, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529b80_0, 0, 1;
%delay 30, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529ab0_0, 0, 1;
%pushi/vec4 0, 0, 9;
%store/vec4 v0x152a090_0, 0, 9;
T_6.0 ;
%load/vec4 v0x152a090_0;
%pad/u 32;
%cmpi/u 5, 0, 32;
%jmp/0xz T_6.1, 5;
%delay 200, 0;
%pushi/vec4 0, 0, 9;
%store/vec4 v0x152a200_0, 0, 9;
T_6.2 ;
%load/vec4 v0x152a200_0;
%pad/u 32;
%cmpi/u 9, 0, 32;
%jmp/0xz T_6.3, 5;
%delay 70, 0;
%ix/getv 4, v0x152a090_0;
%load/vec4a v0x1529ff0, 4;
%pushi/vec4 8, 0, 32;
%load/vec4 v0x152a200_0;
%pad/u 32;
%sub;
%part/u 1;
%store/vec4 v0x1529b80_0, 0, 1;
%delay 30, 0;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x1529ab0_0, 0, 1;
%delay 100, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529ab0_0, 0, 1;
%load/vec4 v0x152a200_0;
%pushi/vec4 1, 0, 9;
%add;
%store/vec4 v0x152a200_0, 0, 9;
%jmp T_6.2;
T_6.3 ;
%load/vec4 v0x152a090_0;
%pushi/vec4 1, 0, 9;
%add;
%store/vec4 v0x152a090_0, 0, 9;
%jmp T_6.0;
T_6.1 ;
%delay 200, 0;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x1529b80_0, 0, 1;
%delay 200, 0;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x1529ab0_0, 0, 1;
%delay 40, 0;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x1529b80_0, 0, 1;
%end;
.thread T_6;
.scope S_0x14ddf70;
T_7 ;
%delay 11500, 0;
%vpi_call 2 141 "$finish" {0 0 0};
%end;
.thread T_7;
.scope S_0x14ddf70;
T_8 ;
%vpi_call 2 147 "$dumpfile", "out.vcd" {0 0 0};
%vpi_call 2 148 "$dumpvars", 32'sb00000000000000000000000000000000, S_0x14ddf70 {0 0 0};
%end;
.thread T_8;
.scope S_0x14ddf70;
T_9 ;
%vpi_call 2 153 "$monitor", $stime, " ", v0x1529e90_0, " ", " ", v0x1529ab0_0, " ", v0x1529b80_0, " ", v0x15298e0_0 {0 0 0};
%end;
.thread T_9;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"test_i2c_slave.v";
"i2c_slave.v";

8
i2c_slave/test_i2c_slave/readme.txt

@ -0,0 +1,8 @@
For simulation type command like:
iverilog -o qqq i2c_slave.v test_i2c_slave_tx.v // FOR TX TO SLAVE
iverilog -o qqq i2c_slave.v test_i2c_slave_rx.v // FOR RX FROM SLAVE
Then type command:
vvp qqq
And open out.vcd with gtkwave

155
i2c_slave/test_i2c_slave/test_i2c_slave_rx.v

@ -0,0 +1,155 @@
module test_counter;
reg clk, SCL, SDA;
wire SDA_OUT, I2C_ACTIVITY, I2C_READ, ACK, WR;
wire [7:0] received_byte, byte_to_transmit;
reg [7:0] to_tx = 8'hC5;
wire [8:0] i2c_counter;
reg [8:0] i, j;
reg [8:0] data_to [4:0]/* = { 9'h98, 9'h00, 9'h23, 9'h10, 9'h98 }*/;
//reg [8:0] data_to = 9'h98;
//устанавливаем экземпляр тестируемого модуля
i2c_slave i2c(clk, SCL, SDA, SDA_OUT, I2C_ACTIVITY, I2C_READ, ACK, WR, received_byte, byte_to_transmit, i2c_counter);
//module i2c_slave (input CLK,
// input SCL, /*inout SDA,*/SDA_IN, output SDA_OUT, // FOR TEST
// output IS_TRANSMISSION, output IS_READ, output IS_ACK, output WR, //output ACK_MASTER_CTRL,
// output reg [7:0] RECEIVED_BYTE, input [7:0] BYTE_TO_TRANSMIT,
// output [(MAX_I2C_TRANSACTION_EXP2-1):0] COUNTER);
//моделируем сигнал тактовой частоты
always
begin
#1 clk = ~clk;
/*data_to[0] = 9'hd0; // TX (ADRESS 34)
data_to[1] = 9'h00;
data_to[2] = 9'h46;
data_to[3] = 9'h10;
data_to[4] = 9'h98;*/
data_to[0] = 9'hd2; // RX (ADRESS 34)
data_to[1] = 9'h1FE;
data_to[2] = 9'h1FE;
data_to[3] = 9'h1FE;
data_to[4] = 9'h1FF;
end
//от начала времени...
parameter SDA_STT = 30;
parameter SCL_H = 100;
parameter SCL_L1 = 70;
parameter SCL_L2 = 30;
assign byte_to_transmit = to_tx;
initial
begin
//byte_to_transmit = 8'hC5;
clk = 0;
SCL = 1;
//SDA_CTRL = 1;
to_tx = 8'hC5;
SDA = 1;
#500 SDA = 0;
#SDA_STT SCL = 0;
for (i = 0; i < 5; i++)
begin
#200 for (j = 0; j < 9; j++)
begin
#SCL_L1 SDA = data_to[i][8-j]; // first bit start
#SCL_L2 SCL = 1; // CLOCK of first bit
#SCL_H SCL = 0;
end
end
#200 SDA = 0;
#200 SCL = 1;
#40 SDA = 1;
/*
#SCL_L1 SDA = 1; // first bit start
#SCL_L2 SCL = 1; // CLOCK of first bit
#SCL_H SCL = 0; // bit 7
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 6
#SCL_L1 SDA = 1;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 5
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 4
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 4
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 3
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 2
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 1
*/
end
/*
//через временной интервал "50" подаем сигнал сброса
#50 SCL = 1;
//еще через время "4" снимаем сигнал сброса
#4 SCL = 0;
//пауза длительностью "50"
#50;
//ждем фронта тактовой частоты и сразу после нее подаем сигнал записи
@(posedge clk)
#0
begin
SDA = 0;
//wr = 1'b1;
end
//по следующему фронту снимаем сигнал записи
@(posedge clk)
#0
begin
SDA = 1;
//wr = 1'b0;
end
end
*/
//заканчиваем симуляцию в момент времени "400"
initial
begin
#11500 $finish;
end
//создаем файл VCD для последующего анализа сигналов
initial
begin
$dumpfile("out.vcd");
$dumpvars(0,test_counter);
end
//наблюдаем на некоторыми сигналами системы
initial
$monitor($stime,, clk,,, SCL,, SDA,, I2C_ACTIVITY);
endmodule

155
i2c_slave/test_i2c_slave/test_i2c_slave_tx.v

@ -0,0 +1,155 @@
module test_counter;
reg clk, SCL, SDA;
wire SDA_OUT, I2C_ACTIVITY, I2C_READ, ACK, WR;
wire [7:0] received_byte, byte_to_transmit;
reg [7:0] to_tx = 8'hC5;
wire [8:0] i2c_counter;
reg [8:0] i, j;
reg [8:0] data_to [4:0]/* = { 9'h98, 9'h00, 9'h23, 9'h10, 9'h98 }*/;
//reg [8:0] data_to = 9'h98;
//устанавливаем экземпляр тестируемого модуля
i2c_slave i2c(clk, SCL, SDA, SDA_OUT, I2C_ACTIVITY, I2C_READ, ACK, WR, received_byte, byte_to_transmit, i2c_counter);
//module i2c_slave (input CLK,
// input SCL, /*inout SDA,*/SDA_IN, output SDA_OUT, // FOR TEST
// output IS_TRANSMISSION, output IS_READ, output IS_ACK, output WR, //output ACK_MASTER_CTRL,
// output reg [7:0] RECEIVED_BYTE, input [7:0] BYTE_TO_TRANSMIT,
// output [(MAX_I2C_TRANSACTION_EXP2-1):0] COUNTER);
//моделируем сигнал тактовой частоты
always
begin
#1 clk = ~clk;
data_to[0] = 9'hd0; // TX (ADRESS 34)
data_to[1] = 9'h00;
data_to[2] = 9'h46;
data_to[3] = 9'h10;
data_to[4] = 9'h98;
/*data_to[0] = 9'hd2; // RX (ADRESS 34)
data_to[1] = 9'h1FE;
data_to[2] = 9'h1FE;
data_to[3] = 9'h1FE;
data_to[4] = 9'h1FF;*/
end
//от начала времени...
parameter SDA_STT = 30;
parameter SCL_H = 100;
parameter SCL_L1 = 70;
parameter SCL_L2 = 30;
assign byte_to_transmit = to_tx;
initial
begin
//byte_to_transmit = 8'hC5;
clk = 0;
SCL = 1;
//SDA_CTRL = 1;
to_tx = 8'hC5;
SDA = 1;
#500 SDA = 0;
#SDA_STT SCL = 0;
for (i = 0; i < 5; i++)
begin
#200 for (j = 0; j < 9; j++)
begin
#SCL_L1 SDA = data_to[i][8-j]; // first bit start
#SCL_L2 SCL = 1; // CLOCK of first bit
#SCL_H SCL = 0;
end
end
#200 SDA = 0;
#200 SCL = 1;
#40 SDA = 1;
/*
#SCL_L1 SDA = 1; // first bit start
#SCL_L2 SCL = 1; // CLOCK of first bit
#SCL_H SCL = 0; // bit 7
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 6
#SCL_L1 SDA = 1;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 5
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 4
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 4
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 3
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 2
#SCL_L1 SDA = 0;
#SCL_L2 SCL = 1;
#SCL_H SCL = 0; // 1
*/
end
/*
//через временной интервал "50" подаем сигнал сброса
#50 SCL = 1;
//еще через время "4" снимаем сигнал сброса
#4 SCL = 0;
//пауза длительностью "50"
#50;
//ждем фронта тактовой частоты и сразу после нее подаем сигнал записи
@(posedge clk)
#0
begin
SDA = 0;
//wr = 1'b1;
end
//по следующему фронту снимаем сигнал записи
@(posedge clk)
#0
begin
SDA = 1;
//wr = 1'b0;
end
end
*/
//заканчиваем симуляцию в момент времени "400"
initial
begin
#11500 $finish;
end
//создаем файл VCD для последующего анализа сигналов
initial
begin
$dumpfile("out.vcd");
$dumpvars(0,test_counter);
end
//наблюдаем на некоторыми сигналами системы
initial
$monitor($stime,, clk,,, SCL,, SDA,, I2C_ACTIVITY);
endmodule
Loading…
Cancel
Save