Commit e2d418c6 authored by Tristan Gingold's avatar Tristan Gingold

Merge branch '31-ciwbmasteraccessor-handle-multiple-requests' into 'proposed_master'

hdl/sim: Protect CIWBMasterAccessor against multiple requests

See merge request !19
parents 17140a58 e85a2855
......@@ -72,8 +72,8 @@ interface IWishboneMaster
WAIT_ACK
} xf_state;
wb_cycle_t request_queue[$];
wb_cycle_t result_queue[$];
mailbox #(wb_cycle_t) request_queue;
mailbox #(wb_cycle_t) result_queue;
struct {
int gen_random_throttling;
......@@ -283,35 +283,29 @@ class CIWBMasterAccessor extends CWishboneAccessor;
endfunction // poll
task get(ref wb_cycle_t xfer);
while(!result_queue.size())
@(posedge clk_i);
xfer = result_queue.pop_front();
result_queue.get(xfer);
endtask // get
task put(ref wb_cycle_t xfer);
request_queue.push_back(xfer);
request_queue.put(xfer);
endtask // put
function int idle();
return (request_queue.size() == 0) && (xf_state == IDLE);
return (request_queue.num() == 0) && (xf_state == IDLE);
endfunction // idle
endclass // CIWBMasterAccessor
CIWBMasterAccessor theAccessor;
initial
theAccessor = new;
function automatic CIWBMasterAccessor get_accessor();
return theAccessor;
endfunction // get_accessor
always@(posedge clk_i)
if (!rst_n_i) begin
request_queue = {};
result_queue = {};
request_queue = new();
result_queue = new();
xf_state = IDLE;
cyc <= 0;
dat_o <= 0;
......@@ -322,30 +316,38 @@ endclass // CIWBMasterAccessor
end
initial begin
theAccessor = new;
request_queue = new();
result_queue = new();
settings.gen_random_throttling = 0;
settings.throttle_prob = 0.1;
settings.addr_gran = WORD;
end
initial forever begin
@(posedge clk_i);
if (request_queue.size() > 0) begin
forever begin
wb_cycle_t c;
c = request_queue.pop_front();
@(posedge clk_i);
case(c.ctype)
PIPELINED:
pipelined_cycle(c);
CLASSIC:
classic_cycle(c);
endcase
if (request_queue.try_get(c)) begin
result_queue.push_back(c);
end
case (c.ctype)
PIPELINED:
pipelined_cycle(c);
CLASSIC:
classic_cycle(c);
endcase
// Notify any waiting thread that the transfer is complete
->c.done;
result_queue.put(c);
end // if (request_queue.try_get(c))
end // forever begin
end
end // initial begin
endinterface // IWishboneMaster
......@@ -66,8 +66,11 @@ virtual class CWishboneAccessor extends CBusAccessor;
end
// $display("DS: %d", cycle.data.size());
put(cycle);
// wait for the transfer completion notification to avoid getting the result of the wrong transfer
// in case multiple threads are calling readm()/writem() in parallel.
@cycle.done;
get(cycle);
result = cycle.result;
......@@ -91,6 +94,9 @@ virtual class CWishboneAccessor extends CBusAccessor;
end
put(cycle);
// wait for the transfer completion notification to avoid getting the result of the wrong transfer
// in case multiple threads are calling readm()/writem() in parallel.
@cycle.done;
get(cycle);
for(i=0;i < addr.size(); i++)
......
......@@ -42,6 +42,7 @@ typedef struct {
wb_cycle_type_t ctype;
wb_xfer_t data[$];
wb_cycle_result_t result;
event done;
} wb_cycle_t;
typedef enum
......
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