Commit 6b7c7ad9 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

simulation: IWishboneMaster: support for pipelined read transactions

parent 266019c6
...@@ -47,8 +47,9 @@ interface IWishboneMaster ...@@ -47,8 +47,9 @@ interface IWishboneMaster
int gen_random_throttling; int gen_random_throttling;
real throttle_prob; real throttle_prob;
int little_endian; int little_endian;
int cyc_on_stall;
wb_address_granularity_t addr_gran;
} settings; } settings;
modport master modport master
( (
...@@ -66,13 +67,16 @@ interface IWishboneMaster ...@@ -66,13 +67,16 @@ interface IWishboneMaster
); );
function automatic logic[g_addr_width-1:0] gen_addr(uint64_t addr, int xfer_size); function automatic logic[g_addr_width-1:0] gen_addr(uint64_t addr, int xfer_size);
case(g_data_width) if(settings.addr_gran == WORD)
8: return addr; case(g_data_width)
16: return addr >> 1; 8: return addr;
32: return addr >> 2; 16: return addr >> 1;
64: return addr >> 3; 32: return addr >> 2;
default: $error("IWishbone: invalid WB data bus width [%d bits\n]", g_data_width); 64: return addr >> 3;
endcase // case (xfer_size) default: $error("IWishbone: invalid WB data bus width [%d bits\n]", g_data_width);
endcase // case (xfer_size)
else
return addr;
endfunction endfunction
function automatic logic[63:0] rev_bits(logic [63:0] x, int nbits); function automatic logic[63:0] rev_bits(logic [63:0] x, int nbits);
...@@ -194,28 +198,41 @@ interface IWishboneMaster ...@@ -194,28 +198,41 @@ interface IWishboneMaster
if (ack) if (ack)
ack_cnt--; ack_cnt--;
endtask endtask
task automatic handle_readback(ref wb_xfer_t xf [$], input int read, ref int cur_rdbk);
if(ack && read)
begin
xf[cur_rdbk].d = dat_i;
cur_rdbk++;
end
endtask // handle_readback
task automatic pipelined_write_cycle task automatic pipelined_cycle
( (
wb_xfer_t xfer[], ref wb_xfer_t xfer[$],
int n_xfers, input int write,
input int n_xfers,
output wb_cycle_result_t result output wb_cycle_result_t result
); );
int i; int i;
int ack_count ; int ack_count ;
int failure ; int failure ;
int cur_rdbk;
ack_count = 0; ack_count = 0;
failure = 0; failure = 0;
xf_idle = 0; xf_idle = 0;
cur_rdbk = 0;
if($time != last_access_t) if($time != last_access_t)
@(posedge clk_i); /* resynchronize, just in case */ @(posedge clk_i); /* resynchronize, just in case */
while(stall) while(stall && !settings.cyc_on_stall)
@(posedge clk_i); @(posedge clk_i);
cyc <= 1'b1; cyc <= 1'b1;
...@@ -226,9 +243,9 @@ interface IWishboneMaster ...@@ -226,9 +243,9 @@ interface IWishboneMaster
while(i<n_xfers) while(i<n_xfers)
begin begin
count_ack(ack_count); count_ack(ack_count);
handle_readback(xfer, !write, cur_rdbk);
if(err) begin if(err) begin
result = R_ERROR; result = R_ERROR;
failure = 1; failure = 1;
...@@ -251,16 +268,25 @@ interface IWishboneMaster ...@@ -251,16 +268,25 @@ interface IWishboneMaster
end else begin end else begin
adr <= gen_addr(xfer[i].a, xfer[i].size); adr <= gen_addr(xfer[i].a, xfer[i].size);
stb <= 1'b1; stb <= 1'b1;
we <= 1'b1; if(write)
sel <= gen_sel(xfer[i].a, xfer[i].size, settings.little_endian); begin
dat_o <= gen_data(xfer[i].a, xfer[i].d, xfer[i].size, settings.little_endian); we <= 1'b1;
sel <= gen_sel(xfer[i].a, xfer[i].size, settings.little_endian);
dat_o <= gen_data(xfer[i].a, xfer[i].d, xfer[i].size, settings.little_endian);
end else begin
we<=1'b0;
sel <= 'hffffffff;
end
@(posedge clk_i); @(posedge clk_i);
stb <= 1'b0; stb <= 1'b0;
we <= 1'b0; we <= 1'b0;
if(stall) if(stall)
begin begin
stb <= 1'b1; stb <= 1'b1;
we <= 1'b1;
if(write)
we <= 1'b1;
while(stall) while(stall)
begin begin
...@@ -296,7 +322,8 @@ interface IWishboneMaster ...@@ -296,7 +322,8 @@ interface IWishboneMaster
count_ack(ack_count); count_ack(ack_count);
handle_readback(xfer, !write, cur_rdbk);
if(stb && !ack) if(stb && !ack)
ack_count++; ack_count++;
else if(!stb && ack) else if(!stb && ack)
...@@ -342,7 +369,7 @@ class CIWBMasterAccessor extends CWishboneAccessor; ...@@ -342,7 +369,7 @@ class CIWBMasterAccessor extends CWishboneAccessor;
return (request_queue.size() == 0) && xf_idle; return (request_queue.size() == 0) && xf_idle;
endfunction // idle endfunction // idle
endclass // CIWBMasterAccessor endclass // CIWBMasterAccessor
function CIWBMasterAccessor get_accessor(); function CIWBMasterAccessor get_accessor();
CIWBMasterAccessor tmp; CIWBMasterAccessor tmp;
...@@ -367,6 +394,8 @@ endclass // CIWBMasterAccessor ...@@ -367,6 +394,8 @@ endclass // CIWBMasterAccessor
initial begin initial begin
settings.gen_random_throttling = 0; settings.gen_random_throttling = 0;
settings.throttle_prob = 0.1; settings.throttle_prob = 0.1;
settings.cyc_on_stall = 0;
settings.addr_gran = WORD;
end end
...@@ -387,12 +416,8 @@ endclass // CIWBMasterAccessor ...@@ -387,12 +416,8 @@ endclass // CIWBMasterAccessor
case(c.ctype) case(c.ctype)
PIPELINED: PIPELINED:
begin begin
if(c.rw) begin pipelined_cycle(c.data, c.rw, c.data.size(), res);
pipelined_write_cycle(c.data, c.data.size(), res); c.result =res;
c.result =res;
c.data = {};
end
end end
CLASSIC: CLASSIC:
begin begin
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment