blob: 360130fce95654c54a632d06c51fde92f4f51a7a [file] [log] [blame]
module Biu1616 (
input clk
, input rst
, input [A-1:0] core_Addr_i
, input [D-1:0] core_Data_i
, output reg [D-1:0] core_Data_o
, input core_rd16
, input core_rd8
, input [ 1:0] core_wr
, output reg core_rdy
, output reg core_done
, output reg [A-1:0] bus_Addr_o
, output reg [A-1:0] bus_Addr_e
, input [D-1:0] bus_Data_i
, output reg [D-1:0] bus_Data_o
, output reg [D-1:0] bus_Data_e
, output reg [B-1:0] bus_stb_o
, output reg [B-1:0] bus_stb_e
, output reg bus_rd_o
, output reg bus_rd_e
, output reg bus_wr_o
, output reg bus_wr_e
, input bus_rdy_i
, input bus_req_i
, output reg bus_ack_o
);
localparam A = 16;
localparam ADRENABLE = {A{1'b1}};
localparam ADRDISABLE = {A{1'b0}};
localparam D = 16;
localparam B = D / 8;
localparam BUSENABLE = {D{1'b0}};
localparam BUSDISABLE = {D{1'b1}};
localparam STBENABLE = {B{1'b0}};
localparam STBDISABLE = {B{1'b1}};
localparam STBACTIVE = 1'b1;
localparam STBINACTIVE = 1'b0;
localparam RDACTIVE = 1'b0;
localparam RDINACTIVE = 1'b1;
localparam RDENABLE = 1'b0;
localparam RDDISABLE = 1'b1;
localparam WRACTIVE = 1'b0;
localparam WRINACTIVE = 1'b1;
localparam WRENABLE = 1'b0;
localparam WRDISABLE = 1'b1;
localparam STATE_RESET = 3'b000; //
localparam STATE_IDLE = 3'b001; //
localparam STATE_16A = 3'b010; //
localparam STATE_16B = 3'b011; //
localparam STATE_16C = 3'b100; //
localparam STATE_16D = 3'b101; //
localparam STATE_BUSR = 3'b110; // Bus access was requested given
wire core_wr16 = core_wr[0] & core_wr[1];
wire core_wr8 = core_wr[0] ^ core_wr[1];
wire core_wrs = (core_wr[0] | core_wr[1]);
wire core_rds = (core_rd16 | core_rd8 );
wire core16 = (core_rd16 | core_wr16 );
wire core8 = (core_rd8 | core_wr8 );
wire unaligned = core_Addr_i[0] & core16;
reg [A-1:0] tAddr;
reg [2:0] pstate, nstate;
always @ (posedge clk or negedge rst)
if( rst == 1'b0 )
pstate = STATE_RESET;
else
pstate = nstate;
always @*
begin
bus_Data_o = bus_Data_o;
bus_Data_e = bus_Data_e;
bus_Addr_o = bus_Addr_o;
bus_Addr_e = ADRENABLE;
bus_ack_o = 1'b0;
bus_rd_o = RDINACTIVE;
bus_rd_e = RDENABLE;
bus_wr_o = WRINACTIVE;
bus_wr_e = WRENABLE;
core_rdy = 1'b0;
core_done = 1'b0;
case(pstate)
STATE_RESET : begin
tAddr = 16'h0000;
bus_Addr_o = 16'h0000;
bus_Data_o = 16'h0000;
bus_Data_e = BUSDISABLE;
core_Data_o = 16'h0000;
bus_stb_o = {B{STBINACTIVE}};
bus_stb_e = STBENABLE;
nstate = STATE_IDLE;
end
STATE_IDLE : begin
tAddr = 16'h0000;
bus_Addr_o = 16'h0000;
bus_Data_o = 16'h0000;
bus_Data_e = BUSDISABLE;
core_Data_o = 16'h0000;
core_rdy = 1'b1;
bus_stb_o = {B{STBINACTIVE}};
bus_stb_e = STBENABLE;
if( bus_req_i == 1'b1 )
nstate = STATE_BUSR;
else if( core16 | core8 )
begin
if( core_wr16 == 1'b1 & core_wr8 == 1'b0 & core_Addr_i[0] == 1'b0 )
begin
tAddr = {core_Addr_i[A-1:1], 1'b0};
bus_Data_o = (core_wrs) ? core_Data_i : 16'h0000;
bus_Data_e = BUSENABLE;
nstate = STATE_16A;
end
else if( core_wr16 == 1'b1 & core_wr8 == 1'b0 & core_Addr_i[0] == 1'b1)
begin
tAddr = core_Addr_i;
bus_Data_o = (core_wrs) ? {core_Data_i[7:0], core_Data_i[7:0]} : 16'h0000;
bus_Data_e = BUSENABLE;
nstate = STATE_16A;
end
else if( core_wr16 == 1'b0 & core_wr[1] == 1'b0 & core_wr[0] == 1'b1 )
begin
tAddr = core_Addr_i;
bus_Data_o = (core_wrs) ? {core_Data_i[7:0], core_Data_i[7:0]} : 16'h0000;
bus_Data_e = BUSENABLE;
nstate = STATE_16A;
end
else if( core_wr16 == 1'b0 & core_wr[1] == 1'b1 & core_wr[0] == 1'b0 )
begin
tAddr = core_Addr_i;
bus_Data_o = (core_wrs) ? {core_Data_i[15:8], core_Data_i[15:8]} : 16'h0000;
bus_Data_e = BUSENABLE;
nstate = STATE_16A;
end
else
begin
tAddr = core_Addr_i;
bus_Data_o = 0;
bus_Data_e = BUSENABLE;
nstate = STATE_16A;
end
end
else
nstate = STATE_IDLE;
end
STATE_16A : begin
if( core16 & core_Addr_i[0] == 1'b0)
bus_stb_o = {B{STBACTIVE}};
else
bus_stb_o = { ( tAddr[0]) ? STBACTIVE : STBINACTIVE,
(~tAddr[0]) ? STBACTIVE : STBINACTIVE};
bus_stb_e = STBENABLE;
bus_Addr_o = tAddr;
bus_rd_o = (core_rds) ? RDACTIVE : RDINACTIVE;
bus_wr_o = (core_wrs) ? WRACTIVE : WRINACTIVE;
nstate = STATE_16B;
end
STATE_16B : begin
if( core_rd16 == 1'b1 & core_Addr_i[0] == 1'b0 )
core_Data_o = bus_Data_i;
else if( bus_stb_o[1] )
core_Data_o = bus_Data_i[15:8];
else
core_Data_o = bus_Data_i[7:0];
bus_stb_o = bus_stb_o;
bus_stb_e = STBENABLE;
bus_rd_o = (core_rds) ? RDACTIVE : RDINACTIVE;
bus_wr_o = (core_wrs) ? WRACTIVE : WRINACTIVE;
if( bus_rdy_i == 1'b1 & unaligned == 1'b1 )
begin
tAddr = tAddr + 1;
nstate = STATE_16C;
core_done = 1'b0;
end
else if( bus_rdy_i == 1'b1 & unaligned == 1'b0 )
begin
nstate = STATE_IDLE;
core_done = 1'b1;
end
else
begin
nstate = STATE_16B;
core_done = 1'b0;
end
end
STATE_16C : begin
if( core_wrs )
begin
bus_Data_o = {8'h00, core_Data_i[15:8]};
bus_Data_e = BUSENABLE;
end
else
begin
bus_Data_o = 0;
bus_Data_e = BUSDISABLE;
end
bus_Addr_o = tAddr;
bus_stb_o = {STBINACTIVE, STBACTIVE};
bus_stb_e = STBENABLE;
bus_rd_o = (core_rds) ? RDACTIVE : RDINACTIVE;
bus_wr_o = (core_wrs) ? WRACTIVE : WRINACTIVE;
nstate = STATE_16D;
end
STATE_16D : begin
core_Data_o[15:8] = bus_Data_i[7:0];
bus_stb_o = bus_stb_o;
bus_stb_e = STBENABLE;
bus_rd_o = (core_rds) ? RDACTIVE : RDINACTIVE;
bus_wr_o = (core_wrs) ? WRACTIVE : WRINACTIVE;
core_done = bus_rdy_i;
if( bus_rdy_i == 1'b1 )
nstate = STATE_IDLE;
else
nstate = STATE_16D;
end
STATE_BUSR : begin
bus_Addr_e = ADRDISABLE;
bus_Data_e = BUSDISABLE;
bus_stb_o = STBINACTIVE;
bus_stb_o = STBDISABLE;
bus_rd_o = RDINACTIVE;
bus_rd_e = RDDISABLE;
bus_wr_o = WRINACTIVE;
bus_wr_e = WRDISABLE;
bus_ack_o = 1'b1;
if( bus_req_i == 1'b1 )
nstate = STATE_BUSR;
else
nstate = STATE_IDLE;
end
default : begin
nstate = STATE_RESET;
end
endcase
end
endmodule