Line 8... |
Line 8... |
|
|
module
|
module
|
i2c_to_wb_top
|
i2c_to_wb_top
|
#(
|
#(
|
parameter DW = 32,
|
parameter DW = 32,
|
parameter AW = 32
|
parameter AW = 8
|
)
|
)
|
(
|
(
|
input i2c_data_in,
|
input i2c_data_in,
|
input i2c_clk_in,
|
input i2c_clk_in,
|
output i2c_data_out,
|
output i2c_data_out,
|
output i2c_clk_out,
|
output i2c_clk_out,
|
output i2c_data_oe,
|
output i2c_data_oe,
|
output i2c_clk_oe,
|
output i2c_clk_oe,
|
|
|
|
input [3:0] thd_dat,
|
|
|
input [(DW-1):0] wb_data_i,
|
input [(DW-1):0] wb_data_i,
|
output [(DW-1):0] wb_data_o,
|
output [(DW-1):0] wb_data_o,
|
output [(AW-1):0] wb_addr_o,
|
output [(AW-1):0] wb_addr_o,
|
output [3:0] wb_sel_o,
|
output [3:0] wb_sel_o,
|
output wb_we_o,
|
output wb_we_o,
|
Line 33... |
Line 35... |
|
|
input wb_clk_i,
|
input wb_clk_i,
|
input wb_rst_i
|
input wb_rst_i
|
);
|
);
|
|
|
|
// --------------------------------------------------------------------
|
|
// wires
|
|
// wire tip_byte;
|
|
wire tip_addr_byte;
|
|
wire tip_read_byte;
|
|
wire tip_write_byte;
|
|
wire tip_wr_ack;
|
|
wire tip_rd_ack;
|
|
wire tip_addr_ack;
|
|
// wire tip_ack;
|
|
// wire tip_write;
|
|
// wire tip_read;
|
|
|
|
wire i2c_ack_out = 1'b0;
|
|
wire i2c_ack_done;
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
// glitch filter
|
// glitch filter
|
|
|
wire gf_i2c_data_in;
|
wire gf_i2c_data_in;
|
Line 71... |
Line 88... |
.rst(wb_rst_i)
|
.rst(wb_rst_i)
|
);
|
);
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
// bit counter
|
// i2c data
|
reg [3:0] bit_count;
|
|
wire ack_done = (bit_count > 4'h8) & gf_i2c_clk_in_rise;
|
|
|
|
always @(posedge wb_clk_i or posedge wb_rst_i)
|
|
if( wb_rst_i | ack_done )
|
|
bit_count <= 4'h0;
|
|
else if( gf_i2c_clk_in_fall )
|
|
bit_count <= bit_count + 1;
|
|
|
|
|
|
// --------------------------------------------------------------------
|
reg [8:0] i2c_data_in_r; // add throw away bit for serial_out
|
// start & stop
|
reg parallel_load_r;
|
|
wire parallel_load = ~parallel_load_r & tip_read_byte;
|
|
wire [7:0] parallel_load_data = 8'h11;
|
|
wire serial_out = i2c_data_in_r[8];
|
|
|
reg gf_i2c_data_in_fall_reg;
|
|
always @(posedge wb_clk_i)
|
always @(posedge wb_clk_i)
|
gf_i2c_data_in_fall_reg <= gf_i2c_data_in_fall;
|
parallel_load_r <= tip_read_byte;
|
|
|
reg gf_i2c_data_in_rise_reg;
|
|
always @(posedge wb_clk_i)
|
always @(posedge wb_clk_i)
|
gf_i2c_data_in_rise_reg <= gf_i2c_data_in_rise;
|
if( parallel_load )
|
|
i2c_data_in_r[7:0] <= parallel_load_data;
|
wire start_detected = gf_i2c_data_in_fall_reg & gf_i2c_clk_in;
|
else if( (tip_write_byte & gf_i2c_clk_in_rise) | (tip_read_byte & gf_i2c_clk_in_fall) )
|
wire stop_detected = gf_i2c_data_in_rise_reg & gf_i2c_clk_in;
|
i2c_data_in_r <= {i2c_data_in_r[7:0], gf_i2c_data_in};
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
// transmition in progress
|
// wishbone stuff
|
|
|
reg tip_slave_address;
|
|
|
|
|
reg [7:0] i2c_address_r;
|
always @(posedge wb_clk_i)
|
always @(posedge wb_clk_i)
|
if( ack_done | wb_rst_i )
|
if( tip_addr_ack )
|
tip_slave_address <= 1'b0;
|
i2c_address_r <= 8'h00;
|
else if( start_detected )
|
else if( i2c_ack_done )
|
tip_slave_address <= 1'b1;
|
i2c_address_r <= i2c_address_r + 1;
|
|
|
reg tip;
|
|
|
|
always @(posedge wb_clk_i)
|
// --------------------------------------------------------------------
|
if( wb_rst_i )
|
// state machine
|
tip <= 0;
|
i2c_to_wb_fsm
|
else if( start_detected | stop_detected )
|
i_i2c_to_wb_fsm
|
tip <= start_detected;
|
(
|
|
.i2c_data(gf_i2c_data_in),
|
|
.i2c_data_rise(gf_i2c_data_in_rise),
|
|
.i2c_data_fall(gf_i2c_data_in_fall),
|
|
|
|
.i2c_clk(gf_i2c_clk_in),
|
|
.i2c_clk_rise(gf_i2c_clk_in_rise),
|
|
.i2c_clk_fall(gf_i2c_clk_in_fall),
|
|
|
|
.i2c_bit_7(i2c_data_in_r[7]),
|
|
.i2c_ack_done(i2c_ack_done),
|
|
|
|
.tip_addr_byte(tip_addr_byte),
|
|
// .tip_byte(tip_byte),
|
|
.tip_read_byte(tip_read_byte),
|
|
.tip_write_byte(tip_write_byte),
|
|
.tip_wr_ack(tip_wr_ack),
|
|
.tip_rd_ack(tip_rd_ack),
|
|
.tip_addr_ack(tip_addr_ack),
|
|
// .tip_ack(tip_ack),
|
|
// .tip_write(tip_write),
|
|
// .tip_read(tip_read),
|
|
|
wire bit_ack_detected = (bit_count == 4'h9) & tip;
|
.state_out(),
|
|
|
|
.wb_clk_i(wb_clk_i),
|
|
.wb_rst_i(wb_rst_i)
|
|
);
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
// ack flop
|
// i2c_data out sync
|
reg ack_bit_r;
|
|
|
|
|
reg i2c_data_oe_r;
|
always @(posedge wb_clk_i)
|
always @(posedge wb_clk_i)
|
if( wb_rst_i )
|
if( wb_rst_i )
|
ack_bit_r <= 1'b0;
|
i2c_data_oe_r <= 1'b0;
|
else if( bit_ack_detected & gf_i2c_clk_in_fall )
|
else if( gf_i2c_clk_in_fall )
|
ack_bit_r <= i2c_data_in;
|
i2c_data_oe_r <= tip_read_byte | tip_wr_ack;
|
|
|
|
reg i2c_data_mux_select_r;
|
|
always @(posedge wb_clk_i)
|
|
if( gf_i2c_clk_in_fall )
|
|
i2c_data_mux_select_r <= tip_wr_ack;
|
|
|
|
|
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
// outputs
|
// outputs
|
assign i2c_data_out = 1'b1;
|
|
|
assign i2c_data_out = i2c_data_mux_select_r ? i2c_ack_out : serial_out;
|
|
assign i2c_data_oe = i2c_data_oe_r;
|
assign i2c_clk_out = 1'b1;
|
assign i2c_clk_out = 1'b1;
|
assign i2c_data_oe = 1'b0;
|
|
assign i2c_clk_oe = 1'b0;
|
assign i2c_clk_oe = 1'b0;
|
|
|
|
assign wb_cyc_o = tip_wr_ack | tip_rd_ack;
|
|
assign wb_addr_o[7:0] = i2c_address_r;
|
|
assign wb_we_o = tip_wr_ack;
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|