I am using the UART core in 32-bit configuration (BIG ENDIAN). The UART does not respond correctly to the SEL_I signal.
The simplest case to exhibit the problem is as follows (all wishbone transactions):
reset UART read from Receive buffer \w SEL_I = 4'b0001 wb_adr_i = 32'h00000000
I expect wb_dat_o7:0 = 8'hxx but get wb_dat_o7:0 = 8'h00
But if I set SEL_I = 4'b1000 wb_dat_o31:24 =8'hxx as expected.
for the case SEL_I = 4'b0001 wb_interface sends wb_adr_int = 8'h03 to regs
The following code will not select the correct output
// Asynchronous reading here because the outputs are sampled in uart_wb.v file
always @(dl or dlab or ier or iir or scratch
or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i) // asynchrounous reading
begin
case (wb_addr_i)
UART_REG_RB : wb_dat_o = dlab ? dl[
UART_DL1] : rf_data_out10:3;
UART_REG_IE : wb_dat_o = dlab ? dl[
UART_DL2] : ier;
UART_REG_II : wb_dat_o = {4'b1100,iir};
UART_REG_LC : wb_dat_o = lcr;
UART_REG_LS : wb_dat_o = lsr;
UART_REG_MS : wb_dat_o = msr;
`UART_REG_SR : wb_dat_o = scratch;
default: wb_dat_o = 8'b0; // ??
endcase // case(wb_addr_i)
end // always @ (dl or dlab or ier or iir or scratch...
I would expect
UART_REG_RB : wb_dat_o = dlab ? dl[
UART_DL1] : rf_data_out10:3;
to execute but since wb_addr_i = 8'h03 it will not execute.
Answer: First of all let me tell you, that the UART16550 is used in 32-bit BIGENDIAN mode in our system and it works without any problems. Now let's go to the problem. You didn't understand the functionality of the UART16650 core. If you make a 32-bit big_endian read to the address 0x0 and use select = 0x1, this means that you're reading from the address 0x3 (on the 8-bit bus).
So the address wb_adr_i = 0x0 + wb_sel_i = 0x1 is changed to address wb_adr_int = 0x3, which is used for reading the data from the registers.
If you have further problems, contact me directly at igor.mohor@gmail.com
Best regards, Igor
You need to `define LITLE_ENDIAN in the uart_defines.v file if you want little endian.
It is missing from that file
John Eaton