- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am connecting an I2C core to a ColdFire V1 IP Core using the Avalon Bus in SOPC. I get a warning about the slave (I2C core), which has 8-bit registers, not having byteenables. Then it says Narrow (less than 32-bit) writes from the cpu core will result in spurious writes to the I2C slave. I also notice that when I write to addresses in memory (RAM), they get written to correctly whether writing using a 32-bit int or a 4 successive writes with char type (8-bit), but when writing to the I2C core, I have to write all 4 registers (are at 4 successive address in the I2C Core) at once, but if I try to write them as bytes, things get hosed. :confused: SalmanLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would ignore the 2 LSBs of the address bus and add a byteenable[1:0] in the I2C module and use those two bits internally as your 2 LSBs of the address.
Boris- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Boris thanks for responding. Okay, now why do I need 2 bits for byte enable? I have the following code for the writing of internal 8-bit registers using just 3 bits of the address for the write and just one byte for the write data register :
// avalon signals input clk; // master clock input input reset_n; // asynchronous reset input [2:0] address; // lower address bits output [7:0] writedata; // databus output input wr; // write input input rd; // read input reg [7:0] writedata; always @(posedge clk) begin //if (~wr & rd) if (wr & ~rd) case (address) // synopsys parallel_case 3'b000: writedata <=# 1 prer[ 7:0]; 3'b001: writedata <=# 1 prer[15:8]; 3'b010: writedata <=# 1 ctr; 3'b011: writedata <=# 1 rxr; // write is transmit register (txr) 3'b100: writedata <=# 1 sr; // write is command register (cr) 3'b101: writedata <=# 1 txr; 3'b110: writedata <=# 1 cr; 3'b111: writedata <=# 1 0; // reserved endcase end- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First the avalon bus structure by default is 32-bit data, word addressing, using byteenables. When a slave is only 8-bits wide the SOPC builder will generate a 32-bit to 8-bit converter. This converter needs the byteeneables from the slave to be able to tell which specific byte address to write/read. Otherwise each read/write on the avalon will be a word access and the converter will perform 4 byte accesses from the slave. This will result in the effect that you are seeing. Just do this in your code.
input [1:0] byteenable; wire [2:0] address_int; assign address_int = {address[2], byteenable}; Use the address_int in your case. Of course you will have to map in the byteenable in the component as well. /Boris- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
BTW does your Coldfire core have byteenables? If not that would explain why this is happening. I have used your method with the NIOS processor and having 8-bit slaves works just fine without byteenables on the slave.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is actually has an AMBA bus but has a wrapper on it so that it works with the SOPC/Avalon bus. I wasn't using the byteenables. I will try using them as per the suggestion. THanks.
.abyteenable (abyteenable) // output: 4-bit Byte Enable [3]=31:24 [2]=23:16 [1]=15:8 [0]=7:0- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yeah try that. I think you can leave your slave alone.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is really best to make your slave 32bits and to ignore the high bits (set to zero on reads).
You probably still want to verify that the byte enable for D0..7 is asserted. Note that the nios cpu always does 32bit reads (all byte enables asserted), discarding the unwanted bits internally. The additional logic for the mux is almost certainly less than that for the bus width adapter!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I agree I try to make all my slaves 32-bit to avoid problems with the different bus widths.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried your suggestion of using the byteenable, but now I have many configuration registers within the i2c module being optimized away (some which I need to stay). Perhaps that byteenable fix isn't going to work for my file or do I need some modification of my top-level IP to make it work? See the attached of what I did.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think I made a mistake when I suggested a solution to you. There are actually 4 byteenable bits in the byteenable bus. One for each byte within the word. You probably need to do the following.
input [3:0] byteenable; wire [2:0] address_int; always (*) begin case(byteenable) 4'b0001: address_int = {address[2], 2'b00}; 4'b0010: address_int = {address[2], 2'b01}; 4'b0100: address_int = {address[2], 2'b10}; 4'b1000: address_int = {address[2], 2'b11}; default: address_int = {address[2], 2'b00}; endcase end Please check out the avalon specification for more information on how byteenables work. /Boris
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page