URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/zipcpu/trunk/rtl
- from Rev 194 to Rev 195
- ↔ Reverse comparison
Rev 194 → Rev 195
/aux/busdelay.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: busdelay.v |
// |
16,14 → 16,28
// *must* know on the first clock whether or not the bus will stall. |
// |
// |
// After a period of time, I started a new design where the timing |
// associated with this original bus clock just wasn't ... fast enough. |
// I needed to delay the stall line as well. A new busdelay was then |
// written and debugged whcih delays the stall line. (I know, you aren't |
// supposed to delay the stall line--but what if you *have* to in order |
// to meet timing?) This new logic has been merged in with the old, |
// and the DELAY_STALL line can be set to non-zero to use it instead |
// of the original logic. Don't use it if you don't need it: it will |
// consume resources and slow your bus down more, but if you do need |
// it--don't be afraid to use it. |
// |
// Both versions of the bus delay will maintain a single access per |
// clock when pipelined, they only delay the time between the strobe |
// going high and the actual command being accomplished. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
39,7 → 53,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
module busdelay(i_clk, |
// The input bus |
48,7 → 62,7
// The delayed bus |
o_dly_cyc, o_dly_stb, o_dly_we, o_dly_addr, o_dly_data, |
i_dly_ack, i_dly_stall, i_dly_data, i_dly_err); |
parameter AW=32, DW=32; |
parameter AW=32, DW=32, DELAY_STALL = 0; |
input i_clk; |
// Input/master bus |
input i_wb_cyc, i_wb_stb, i_wb_we; |
67,35 → 81,100
input [(DW-1):0] i_dly_data; |
input i_dly_err; |
|
initial o_dly_cyc = 1'b0; |
initial o_dly_stb = 1'b0; |
generate |
if (DELAY_STALL != 0) |
begin |
reg r_stb, r_we, r_rtn_stall, r_rtn_err; |
reg [(DW-1):0] r_data; |
reg [(AW-1):0] r_addr; |
|
always @(posedge i_clk) |
o_dly_cyc <= i_wb_cyc; |
// Add the i_wb_cyc criteria here, so we can simplify the o_wb_stall |
// criteria below, which would otherwise *and* these two. |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_stb <= ((i_wb_cyc)&&(i_wb_stb)); |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_we <= i_wb_we; |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_addr<= i_wb_addr; |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_data <= i_wb_data; |
always @(posedge i_clk) |
o_wb_ack <= (i_dly_ack)&&(o_dly_cyc)&&(i_wb_cyc); |
always @(posedge i_clk) |
o_wb_data <= i_dly_data; |
initial o_dly_cyc = 1'b0; |
initial r_rtn_stall= 1'b0; |
initial r_stb = 1'b0; |
always @(posedge i_clk) |
begin |
o_dly_cyc <= (i_wb_cyc); |
|
if (!i_dly_stall) |
begin |
r_we <= i_wb_we; |
r_addr <= i_wb_addr; |
r_data <= i_wb_data; |
|
// Our only non-delayed line, yet still really delayed. Perhaps |
// there's a way to register this? |
// o_wb_stall <= (i_wb_cyc)&&(i_wb_stb) ... or some such? |
// assign o_wb_stall=((i_wb_cyc)&&(i_dly_stall)&&(o_dly_stb));//&&o_cyc |
assign o_wb_stall = ((i_dly_stall)&&(o_dly_stb));//&&o_cyc |
assign o_wb_err = i_dly_err; |
if (r_stb) |
begin |
o_dly_we <= r_we; |
o_dly_addr <= r_addr; |
o_dly_data <= r_data; |
o_dly_stb <= 1'b1; |
r_rtn_stall <= 1'b0; |
r_stb <= 1'b0; |
end else begin |
o_dly_we <= i_wb_we; |
o_dly_addr <= i_wb_addr; |
o_dly_data <= i_wb_data; |
o_dly_stb <= i_wb_stb; |
r_stb <= 1'b0; |
r_rtn_stall <= 1'b0; |
end |
end else if ((!r_stb)&&(!o_wb_stall)) |
begin |
r_we <= i_wb_we; |
r_addr <= i_wb_addr; |
r_data <= i_wb_data; |
r_stb <= i_wb_stb; |
|
r_rtn_stall <= i_wb_stb; |
end |
|
if (!i_wb_cyc) |
begin |
o_dly_stb <= 1'b0; |
r_stb <= 1'b0; |
r_rtn_stall <= 1'b0; |
end |
|
o_wb_ack <= (i_dly_ack)&&(i_wb_cyc)&&(o_dly_cyc); |
o_wb_data <= i_dly_data; |
r_rtn_err <= (i_dly_err)&&(i_wb_cyc)&&(o_dly_cyc); |
end |
|
assign o_wb_stall = r_rtn_stall; |
assign o_wb_err = r_rtn_err; |
|
end else begin |
|
initial o_dly_cyc = 1'b0; |
initial o_dly_stb = 1'b0; |
|
always @(posedge i_clk) |
o_dly_cyc <= i_wb_cyc; |
// Add the i_wb_cyc criteria here, so we can simplify the |
// o_wb_stall criteria below, which would otherwise *and* |
// these two. |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_stb <= ((i_wb_cyc)&&(i_wb_stb)); |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_we <= i_wb_we; |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_addr<= i_wb_addr; |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_data <= i_wb_data; |
always @(posedge i_clk) |
o_wb_ack <= (i_dly_ack)&&(o_dly_cyc)&&(i_wb_cyc); |
always @(posedge i_clk) |
o_wb_data <= i_dly_data; |
|
// Our only non-delayed line, yet still really delayed. Perhaps |
// there's a way to register this? |
// o_wb_stall <= (i_wb_cyc)&&(i_wb_stb) ... or some such? |
// assign o_wb_stall=((i_wb_cyc)&&(i_dly_stall)&&(o_dly_stb));//&&o_cyc |
assign o_wb_stall = ((i_dly_stall)&&(o_dly_stb));//&&o_cyc |
assign o_wb_err = i_dly_err; |
end endgenerate |
|
endmodule |