📄 controller_interface.v
字号:
////////////////////////////////////////////controller_interface.v////////////////////////////////////////// ////Design Engineer: Ravi Gupta ////Company Name : Toomuch Semiconductor//Email : ravi1.gupta@toomuchsemi.com //// // //Purpose : This core will be used as an interface between I2C core and Processor // //Created : 6-12-2007 //// // // //// //// // // // // // // //// ////Modification : Change the control register,added halt reset and inter_rst in control register//////////////////////////////////////////////////////////////////////////////////////////////////////////*// synopsys translate_off`include "oc8051_timescale.v"// synopsys translate_on`include "oc8051_defines.v"*/module processor_interface (clk,rst,add_bus,data_in,data_out,as,ds,rw,bus_busy,byte_trans,slave_addressed,arb_lost,slave_rw,inter,ack_rec, core_en,inter_en,mode,master_rw,ack,rep_start,data,i2c_data,slave_add,time_out_reg,prescale,irq,time_out,inter_rst,halt,data_en,time_rst);input clk; //System clockinput rst; //system reset//signals connecting core to processor/////////////////////////////////////input [7:0]add_bus; //contains address of internal registerinput [7:0]data_in; //trnasport the data for i2c coreinput as; //asserted high indicates vallid address has been placed on the address businput ds; //asserted high indicates valid data on data businput rw; //"1" indicates that processor has to write else readoutput irq; //interrupt to processoroutput inter_rst; //this bit will be written by processor when it will clear the interrupt.output [7:0]data_out;output halt;output data_en;input time_rst;//signals from core to reflect te status of core and buses///////////////////////////////////////////////////////////input bus_busy; //signal from core indicates bus is busyinput byte_trans; //signal from core indicates byte transfer is in progressinput slave_addressed; //signal from core indicares core has been identified as slaveinput arb_lost; //signal from core indicates bus errorinput slave_rw; //signal from core indicates operation of slave coreinput inter; //signal from core.this will interrupt the processor if this bit as well as interrupt enable is highinput ack_rec; //signal from core to reflect the status of ack bitinput time_out;//bits of control register//////////////////////////inout core_en; //this bit must be cleared before any other bit of control register have any effect on coreinout inter_en; //To intrrupt the core this bit must be set when interrupt is pendinginout mode; //Transaction from "0" to "1" directes core to act as master else slaveinout master_rw; //set directiion for master either to transmit or receiveinout ack; //value of acknowledgment bit to be transmitted on SDA line during ack cycleinout rep_start; //set this bit if processor wants a repeated start//data register////////////////inout [7:0]prescale; //contains the value for generating SCL frequencyinout [7:0]time_out_reg; //contains the value for maximum low period for sclinout [7:0]slave_add; //this is the programmble slave addressinout [7:0]data; //data for i2c core input [7:0]i2c_data; //data from core for processor//defining registers addresses/////////////////////////////`define PRER 8'b0000_0010`define CTR 8'b0000_0100`define SR 8'b0000_1000`define TO 8'b0000_1010`define ADDR 8'b0000_1100`define DR 8'b0000_1110`define RR 8'b0000_0000/*//defing the machine state//////////////////////////parameter processor_idle=2'b00;parameter processor_address=2'b01;parameter processor_data=2'b10;parameter processor_ack=2'b11;*///Definig internal registers and wires/////////////////////////////////////wire core_en,inter_en,mode,master_rw,ack,rep_start,inter_rst,halt;wire prescale_reg_en;wire ctr_reg_en;wire sr_reg_en;wire to_reg_en;wire addr_reg_en;wire dr_reg_en;reg [7:0]data_out,sr_reg,ctr_reg,dr_reg,rr_reg;wire [7:0]data_in; //if address on add_bus matches with register address then set this high.wire data_ie; //this is signal used for enaling the data line in read or write cycle.wire as_d; //delay version of address strobe signal for detection of rising and falling edge reg as_delay_sig; //same signal. wire ds_d; //delayed version of data strobe.wire decode;wire rr_reg_en;reg ds_delay_sig;reg prescale_reg_en_sig;assign prescale_reg_en = prescale_reg_en_sig;reg ctr_reg_en_sig;assign ctr_reg_en = ctr_reg_en_sig;reg sr_reg_en_sig;assign sr_reg_en = sr_reg_en_sig;reg to_reg_en_sig;assign to_reg_en = to_reg_en_sig;reg addr_reg_en_sig;assign addr_reg_en = addr_reg_en_sig;reg dr_reg_en_sig;assign dr_reg_en = dr_reg_en_sig;reg as_d_sig;assign as_d = as_d_sig;reg ds_d_sig;assign ds_d = ds_d_sig;reg data_ie_sig;assign data_ie = data_ie_sig;//reg core_en_sig;//assign core_en = core_en_sig;//reg inter_en_sig;//assign inter_en = inter_en_sig;//reg mode_sig;//assign mode = mode_sig;//reg master_rw_sig;//assign master_rw = master_rw_sig;//reg ack_sig;//assign ack = ack_sig;//reg rep_start_sig;//assign rep_start = rep_start_sig;reg [7:0]data_sig;assign data = dr_reg;reg [7:0]prescale_sig;assign prescale = prescale_sig;reg [7:0]time_out_sig;assign time_out_reg = time_out_sig;reg [7:0]slave_add_sig;assign slave_add = slave_add_sig;//reg [7:0]data_out_sig;//assign data_out = data_out_sig;reg decode_sig;assign decode = decode_sig;//reg inter_rst_sig;//assign inter_rst = inter_rst_sig;//reg halt_sig;//assign halt = halt_sig;assign data_en = dr_reg_en_sig;reg rr_reg_en_sig;assign rr_reg_en = rr_reg_en_sig;assign core_en = ctr_reg [7]; assign inter_en = ctr_reg [6];assign mode = ctr_reg [5];assign master_rw = ctr_reg [4];assign ack = ctr_reg [3];assign rep_start = ctr_reg [2];assign inter_rst = ctr_reg [1];assign halt = ctr_reg [0];//generating delayed version of inputs for detection of rising and falling edge.//////////////////////////////////////////////////////////////////////////////always@(posedge clk or posedge rst)beginif(rst)begin as_delay_sig<=1'b0; as_d_sig<=1'b0; ds_delay_sig<=1'b0; ds_d_sig<=1'b0;endelsebegin as_delay_sig<=as; as_d_sig<=as_delay_sig; ds_delay_sig<=ds; ds_d_sig<=ds_delay_sig;endendalways@(posedge clk or posedge rst)begin if(rst) decode_sig<=1'b0; else if(!as_d && as) decode_sig<=1'b1; //else //decode_sig<=1'b0;end//address decoding logic/////////////////////////always@(posedge clk or posedge rst)always@(rst or as or add_bus or posedge time_rst)beginif(rst || time_rst)beginprescale_reg_en_sig<=1'b0;ctr_reg_en_sig<=1'b0;sr_reg_en_sig<=1'b0;to_reg_en_sig<=1'b0;addr_reg_en_sig<=1'b0;dr_reg_en_sig<=1'b0;rr_reg_en_sig <= 1'b0;//add_match_sig<=1'b0;end else if(as)begin if(add_bus == `PRER) begin rr_reg_en_sig <= 1'b0; prescale_reg_en_sig<=1'b1; ctr_reg_en_sig<=1'b0; sr_reg_en_sig<=1'b0; to_reg_en_sig<=1'b0; addr_reg_en_sig<=1'b0; dr_reg_en_sig<=1'b0; //add_match_sig<=1'b1; end else if(add_bus == `CTR) begin rr_reg_en_sig <= 1'b0; prescale_reg_en_sig<=1'b0; ctr_reg_en_sig<=1'b1; sr_reg_en_sig<=1'b0; to_reg_en_sig<=1'b0; addr_reg_en_sig<=1'b0; dr_reg_en_sig<=1'b0; //add_match_sig<=1'b1; end else if(add_bus == `SR) begin rr_reg_en_sig <= 1'b0; prescale_reg_en_sig<=1'b0; ctr_reg_en_sig<=1'b0; sr_reg_en_sig<=1'b1; to_reg_en_sig<=1'b0; addr_reg_en_sig<=1'b0; dr_reg_en_sig<=1'b0; //add_match_sig<=1'b1; end else if(add_bus == `TO) begin rr_reg_en_sig <= 1'b0; prescale_reg_en_sig<=1'b0; ctr_reg_en_sig<=1'b0; sr_reg_en_sig<=1'b0; to_reg_en_sig<=1'b1; addr_reg_en_sig<=1'b0; dr_reg_en_sig<=1'b0; //add_match_sig<=1'b1; end else if(add_bus == `ADDR) begin rr_reg_en_sig <= 1'b0; prescale_reg_en_sig<=1'b0; ctr_reg_en_sig<=1'b0; sr_reg_en_sig<=1'b0; to_reg_en_sig<=1'b0; addr_reg_en_sig<=1'b1; dr_reg_en_sig<=1'b0; //add_match_sig<=1'b1; end else if(add_bus == `DR) begin prescale_reg_en_sig<=1'b0; ctr_reg_en_sig<=1'b0; sr_reg_en_sig<=1'b0; to_reg_en_sig<=1'b0; addr_reg_en_sig<=1'b0; dr_reg_en_sig<=1'b1; rr_reg_en_sig <= 1'b0; //add_match_sig<=1'b1; end else if(add_bus == `RR) begin rr_reg_en_sig <= 1'b1; prescale_reg_en_sig<=1'b0; ctr_reg_en_sig<=1'b0; sr_reg_en_sig<=1'b0; to_reg_en_sig<=1'b0; addr_reg_en_sig<=1'b0; dr_reg_en_sig<=1'b0; //add_match_sig<=1'b1; end else begin rr_reg_en_sig <= 1'b0; prescale_reg_en_sig<=1'b0; ctr_reg_en_sig<=1'b0; sr_reg_en_sig<=1'b0; to_reg_en_sig<=1'b0; addr_reg_en_sig<=1'b0; dr_reg_en_sig<=1'b0; //add_match_sig<=1'b0; endendelsebegin prescale_reg_en_sig<=1'b0; ctr_reg_en_sig<=1'b0; sr_reg_en_sig<=1'b0; to_reg_en_sig<=1'b0; addr_reg_en_sig<=1'b0; dr_reg_en_sig<=1'b0; rr_reg_en_sig <= 1'b0; endend//assigning value of data_ie line//////////////////////////////////always@(posedge clk or posedge rst)begin if(rst) data_ie_sig<=1'b0; else if(!ds_d && ds) data_ie_sig<=1'b1; end//read data to/from the register specified by processor addrress.//always@(rst or addr_reg_en or ctr_reg_en or dr_reg_en or sr_reg_en or prescale_reg_en or to_reg_en or data_ie or rw or data_in )always@(posedge clk or posedge rst)beginif(rst)begin sr_reg <= 8'b0; dr_reg <= 8'b0; rr_reg <= 8'b0; //ctr_reg <= 8'b0;end/*else if(ctr_reg_en) begin //sr_reg <= {byte_trans,slave_addressed,bus_busy,arb_lost,time_out,slave_rw,inter,ack_rec}; ctr_reg <= data_in;end*/elsebegin sr_reg <= {byte_trans,slave_addressed,bus_busy,arb_lost,time_out,slave_rw,inter,ack_rec}; rr_reg <= i2c_data;endendalways@(posedge clk or posedge rst or posedge time_rst)begin if(rst || time_rst) begin //initializing control register ctr_reg <= 8'b0; /*core_en_sig <= 1'b0; inter_en_sig <= 1'b0; mode_sig <= 1'b0; master_rw_sig <= 1'b0; ack_sig <= 1'b0; rep_start_sig <= 1'b0; inter_rst_sig<=1'b0;*/ //initializing data and timer register data_sig <= 8'b00000000; prescale_sig <= 8'b00000000; time_out_sig <= 8'b00000000; data_out <= 8'b00000000; end else if (data_ie) begin //address register if(addr_reg_en) //if address matches with slave address register begin if(rw) //processor write cycle slave_add_sig <= {data_in[7:1] , 1'b0}; else //processor read cycle data_out <= slave_add; end //control register if(ctr_reg_en) //if address matches with cntrol register begin if(rw) //processor write cycle //begin /*core_en_sig <= #2 ctr_reg [7]; inter_en_sig <= #2 ctr_reg [6]; mode_sig <= #2 ctr_reg [5]; master_rw_sig <= #2 ctr_reg [4]; ack_sig <= #2 ctr_reg [3]; rep_start_sig <= #2 ctr_reg [2]; inter_rst_sig <= #2 ctr_reg [1]; halt_sig <= #2 ctr_reg [0];*/ //end //else ctr_reg <= data_in; //processor read cycle else data_out <= ctr_reg; end else if(!byte_trans && bus_busy) ctr_reg[1:0] <= 2'b0; //data register if(dr_reg_en) begin if(rw) dr_reg <= data_in; else data_out <= dr_reg; end if(rr_reg_en) begin data_out <= rr_reg; end //staus register if(sr_reg_en) begin if(!rw) //begin //if(data_in[0]==1'b0) //inter_rst_sig <= 1'b0; //else //inter_rst_sig <= 1'b1; //end //else //begin data_out <= sr_reg; //inter_rst_sig<=1'b0; //end //else //inter_rst_sig<=1'b0; end //prescale register if(prescale_reg_en) begin if(rw) prescale_sig <= data_in; else data_out <= prescale; end //time_out register if(to_reg_en) begin if(rw) time_out_sig <= data_in; else data_out <= time_out_reg; end endend//assigning values to bidirectional bus////////////////////////////////////////assign data_bus = (!rw && data_ie) ? data_out : 8'bzzzzzzzz;//assign data_in = (rw) ? data_bus : 8'bzzzzzzzz;//interuupt pin to processorassign irq = (inter && inter_en) ? 1'b1 : 1'b0;endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -