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/aux
- from Rev 34 to Rev 36
- ↔ Reverse comparison
Rev 34 → Rev 36
/wbpriarbiter.v
0,0 → 1,118
/////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbpriarbiter.v |
// |
// Project: Zip CPU -- a small, lightweight, RISC CPU soft core |
// |
// Purpose: This is a priority bus arbiter. It allows two separate wishbone |
// masters to connect to the same bus, while also guaranteeing |
// that one master can have the bus with no delay any time the |
// other master is not using the bus. The goal is to eliminate |
// the combinatorial logic required in the other wishbone |
// arbiter, while still guarateeing access time for the priority |
// channel. |
// |
// The core logic works like this: |
// |
// 1. When no one requests the bus, 'A' is granted the bus and |
// guaranteed that any access will go right through. |
// 2. If 'B' requests the bus (asserts cyc), and the bus is idle, |
// then 'B' will be granted the bus. |
// 3. Bus grants last as long as the 'cyc' line is high. |
// 4. Once 'cyc' is dropped, the bus returns to 'A' as the owner. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Tecnology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, 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 |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
// |
module wbpriarbiter(i_clk, i_rst, |
// Bus A |
i_a_cyc, i_a_stb, i_a_we, i_a_adr, i_a_dat, o_a_ack, o_a_stall, o_a_err, |
// Bus B |
i_b_cyc, i_b_stb, i_b_we, i_b_adr, i_b_dat, o_b_ack, o_b_stall, o_b_err, |
// Both buses |
o_cyc, o_stb, o_we, o_adr, o_dat, i_ack, i_stall, i_err); |
parameter DW=32, AW=32; |
// Wishbone doesn't use an i_ce signal. While it could, they dislike |
// what it would (might) do to the synchronous reset signal, i_rst. |
input i_clk, i_rst; |
// Bus A |
input i_a_cyc, i_a_stb, i_a_we; |
input [(AW-1):0] i_a_adr; |
input [(DW-1):0] i_a_dat; |
output wire o_a_ack, o_a_stall, o_a_err; |
// Bus B |
input i_b_cyc, i_b_stb, i_b_we; |
input [(AW-1):0] i_b_adr; |
input [(DW-1):0] i_b_dat; |
output wire o_b_ack, o_b_stall, o_b_err; |
// |
output wire o_cyc, o_stb, o_we; |
output wire [(AW-1):0] o_adr; |
output wire [(DW-1):0] o_dat; |
input i_ack, i_stall, i_err; |
|
// Go high immediately (new cycle) if ... |
// Previous cycle was low and *someone* is requesting a bus cycle |
// Go low immadiately if ... |
// We were just high and the owner no longer wants the bus |
// WISHBONE Spec recommends no logic between a FF and the o_cyc |
// This violates that spec. (Rec 3.15, p35) |
assign o_cyc = (r_a_owner) ? i_a_cyc : i_b_cyc; |
reg r_a_owner; |
initial r_a_owner = 1'b1; |
always @(posedge i_clk) |
if (~i_b_cyc) |
r_a_owner <= 1'b1; |
else if ((i_b_cyc)&&(~i_a_cyc)) |
r_a_owner <= 1'b0; |
|
|
// Realistically, if neither master owns the bus, the output is a |
// don't care. Thus we trigger off whether or not 'A' owns the bus. |
// If 'B' owns it all we care is that 'A' does not. Likewise, if |
// neither owns the bus than the values on the various lines are |
// irrelevant. |
assign o_stb = (r_a_owner) ? i_a_stb : i_b_stb; |
assign o_we = (r_a_owner) ? i_a_we : i_b_we; |
assign o_adr = (r_a_owner) ? i_a_adr : i_b_adr; |
assign o_dat = (r_a_owner) ? i_a_dat : i_b_dat; |
|
// We cannot allow the return acknowledgement to ever go high if |
// the master in question does not own the bus. Hence we force it |
// low if the particular master doesn't own the bus. |
assign o_a_ack = ( r_a_owner) ? i_ack : 1'b0; |
assign o_b_ack = (~r_a_owner) ? i_ack : 1'b0; |
|
// Stall must be asserted on the same cycle the input master asserts |
// the bus, if the bus isn't granted to him. |
assign o_a_stall = ( r_a_owner) ? i_stall : 1'b1; |
assign o_b_stall = (~r_a_owner) ? i_stall : 1'b1; |
|
// |
// |
assign o_a_err = ( r_a_owner) ? i_err : 1'b0; |
assign o_b_err = (~r_a_owner) ? i_err : 1'b0; |
|
endmodule |
|
/wbarbiter.v
57,11 → 57,11
`define WBA_ALTERNATING |
module wbarbiter(i_clk, i_rst, |
// Bus A |
i_a_adr, i_a_dat, i_a_we, i_a_stb, i_a_cyc, o_a_ack, o_a_stall, |
i_a_adr, i_a_dat, i_a_we, i_a_stb, i_a_cyc, o_a_ack, o_a_stall, o_a_err, |
// Bus B |
i_b_adr, i_b_dat, i_b_we, i_b_stb, i_b_cyc, o_b_ack, o_b_stall, |
i_b_adr, i_b_dat, i_b_we, i_b_stb, i_b_cyc, o_b_ack, o_b_stall, o_b_err, |
// Both buses |
o_adr, o_dat, o_we, o_stb, o_cyc, i_ack, i_stall); |
o_adr, o_dat, o_we, o_stb, o_cyc, i_ack, i_stall, i_err); |
// 18 bits will address one GB, 4 bytes at a time. |
// 19 bits will allow the ability to address things other than just |
// the 1GB of memory we are expecting. |
73,11 → 73,12
input [(DW-1):0] i_a_dat, i_b_dat; |
input i_a_we, i_a_stb, i_a_cyc; |
input i_b_we, i_b_stb, i_b_cyc; |
output wire o_a_ack, o_b_ack, o_a_stall, o_b_stall; |
output wire o_a_ack, o_b_ack, o_a_stall, o_b_stall, |
o_a_err, o_b_err; |
output wire [(AW-1):0] o_adr; |
output wire [(DW-1):0] o_dat; |
output wire o_we, o_stb, o_cyc; |
input i_ack, i_stall; |
input i_ack, i_stall, i_err; |
|
// All the fancy stuff here is done with the three primary signals: |
// o_cyc |
113,6 → 114,11
wire w_a_owner, w_b_owner; |
`ifdef WBA_ALTERNATING |
reg r_a_last_owner; |
// Stall must be asserted on the same cycle the input master asserts |
// the bus, if the bus isn't granted to him. |
assign o_a_stall = (w_a_owner) ? i_stall : 1'b1; |
assign o_b_stall = (w_b_owner) ? i_stall : 1'b1; |
|
`endif |
always @(posedge i_clk) |
if (i_rst) |
169,10 → 175,10
assign o_a_ack = (w_a_owner) ? i_ack : 1'b0; |
assign o_b_ack = (w_b_owner) ? i_ack : 1'b0; |
|
// Stall must be asserted on the same cycle the input master asserts |
// the bus, if the bus isn't granted to him. |
assign o_a_stall = (w_a_owner) ? i_stall : 1'b1; |
assign o_b_stall = (w_b_owner) ? i_stall : 1'b1; |
// |
// |
assign o_a_err = (w_a_owner) ? i_err : 1'b0; |
assign o_b_err = (w_b_owner) ? i_err : 1'b0; |
|
endmodule |
|
/busdelay.v
44,10 → 44,10
module busdelay(i_clk, |
// The input bus |
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
o_wb_ack, o_wb_stall, o_wb_data, |
o_wb_ack, o_wb_stall, o_wb_data, o_wb_err, |
// 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_ack, i_dly_stall, i_dly_data, i_dly_err); |
parameter AW=32, DW=32; |
input i_clk; |
// Input/master bus |
57,6 → 57,7
output reg o_wb_ack; |
output wire o_wb_stall; |
output reg [(DW-1):0] o_wb_data; |
output wire o_wb_err; |
// Delayed bus |
output reg o_dly_cyc, o_dly_stb, o_dly_we; |
output reg [(AW-1):0] o_dly_addr; |
64,6 → 65,7
input i_dly_ack; |
input i_dly_stall; |
input [(DW-1):0] i_dly_data; |
input i_dly_err; |
|
initial o_dly_cyc = 1'b0; |
initial o_dly_stb = 1'b0; |
91,5 → 93,6
// 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)&&(o_dly_cyc)&&(i_dly_stall)&&(o_dly_stb)); |
assign o_wb_err = i_dly_err; |
|
endmodule |
/wbdblpriarb.v
0,0 → 1,142
/////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbdblpriarb.v |
// |
// Project: Zip CPU -- a small, lightweight, RISC CPU soft core |
// |
// Purpose: This should almost be identical to the priority arbiter, save |
// for a simple diffence: it allows the arbitration of two |
// separate wishbone buses. The purpose of this is to push the address |
// resolution back one cycle, so that by the first clock visible to this |
// core, it is known which of two parts of the bus the desired address |
// will be on, save that we still use the arbiter since the underlying |
// device doesn't know that there are two wishbone buses. |
// |
// So at this point we've deviated from the WB spec somewhat, by allowing |
// two CYC and two STB lines. Everything else is the same. This allows |
// (in this case the Zip CPU) to determine whether or not the access |
// will be to the local ZipSystem bus or the external WB bus on the clock |
// before the local bus access, otherwise peripherals were needing to do |
// multiple device selection comparisons/test within a clock: 1) is this |
// for the local or external bus, and 2) is this referencing me as a |
// peripheral. This then caused the ZipCPU to fail all timing specs. |
// By creating the two pairs of lines, CYC_A/STB_A and CYC_B/STB_B, the |
// determination of local vs external can be made one clock earlier |
// where there's still time for the logic, and the second comparison |
// now has time to complete. |
// |
// So let me try to explain this again. To use this arbiter, one of the |
// two masters sets CYC and STB before, only the master determines which |
// of two address spaces the CYC and STB apply to before the clock and |
// only sets the appropriate CYC and STB lines. Then, on the clock tick, |
// the arbiter determines who gets *both* busses, as they both share every |
// other WB line. Thus, only one of CYC_A and CYC_B going out will ever |
// be high at a given time. |
// |
// Hopefully this makes more sense than it sounds. If not, check out the |
// code below for a better explanation. |
// |
// 20150919 -- Added supported for the WB error signal. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Tecnology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, 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 |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
// |
module wbdblpriarb(i_clk, i_rst, |
// Bus A |
i_a_cyc_a,i_a_cyc_b,i_a_stb_a,i_a_stb_b,i_a_we,i_a_adr, i_a_dat, o_a_ack, o_a_stall, o_a_err, |
// Bus B |
i_b_cyc_a,i_b_cyc_b,i_b_stb_a,i_b_stb_b,i_b_we,i_b_adr, i_b_dat, o_b_ack, o_b_stall, o_b_err, |
// Both buses |
o_cyc_a, o_cyc_b, o_stb_a, o_stb_b, o_we, o_adr, o_dat, |
i_ack, i_stall, i_err); |
parameter DW=32, AW=32; |
// Wishbone doesn't use an i_ce signal. While it could, they dislike |
// what it would (might) do to the synchronous reset signal, i_rst. |
input i_clk, i_rst; |
// Bus A |
input i_a_cyc_a, i_a_cyc_b, i_a_stb_a, i_a_stb_b, i_a_we; |
input [(AW-1):0] i_a_adr; |
input [(DW-1):0] i_a_dat; |
output wire o_a_ack, o_a_stall, o_a_err; |
// Bus B |
input i_b_cyc_a, i_b_cyc_b, i_b_stb_a, i_b_stb_b, i_b_we; |
input [(AW-1):0] i_b_adr; |
input [(DW-1):0] i_b_dat; |
output wire o_b_ack, o_b_stall, o_b_err; |
// |
output wire o_cyc_a,o_cyc_b, o_stb_a, o_stb_b, o_we; |
output wire [(AW-1):0] o_adr; |
output wire [(DW-1):0] o_dat; |
input i_ack, i_stall, i_err; |
|
// All of our logic is really captured in the 'r_a_owner' register. |
// This register determines who owns the bus. If no one is requesting |
// the bus, ownership goes to A on the next clock. Otherwise, if B is |
// requesting the bus and A is not, then ownership goes to not A on |
// the next clock. (Sounds simple ...) |
// |
// The CYC logic is here to make certain that, by the time we determine |
// who the bus owner is, we can do so based upon determined criteria. |
assign o_cyc_a = (~i_rst)&&((r_a_owner) ? i_a_cyc_a : i_b_cyc_a); |
assign o_cyc_b = (~i_rst)&&((r_a_owner) ? i_a_cyc_b : i_b_cyc_b); |
reg r_a_owner; |
initial r_a_owner = 1'b1; |
always @(posedge i_clk) |
if (i_rst) |
r_a_owner <= 1'b1; |
else if ((~o_cyc_a)&&(~o_cyc_b)) |
r_a_owner <= ((i_b_cyc_a)||(i_b_cyc_b))? 1'b0:1'b1; |
|
|
// Realistically, if neither master owns the bus, the output is a |
// don't care. Thus we trigger off whether or not 'A' owns the bus. |
// If 'B' owns it all we care is that 'A' does not. Likewise, if |
// neither owns the bus than the values on these various lines are |
// irrelevant. |
assign o_stb_a = (r_a_owner) ? i_a_stb_a : i_b_stb_a; |
assign o_stb_b = (r_a_owner) ? i_a_stb_b : i_b_stb_b; |
assign o_we = (r_a_owner) ? i_a_we : i_b_we; |
assign o_adr = (r_a_owner) ? i_a_adr : i_b_adr; |
assign o_dat = (r_a_owner) ? i_a_dat : i_b_dat; |
|
// We cannot allow the return acknowledgement to ever go high if |
// the master in question does not own the bus. Hence we force it |
// low if the particular master doesn't own the bus. |
assign o_a_ack = ( r_a_owner) ? i_ack : 1'b0; |
assign o_b_ack = (~r_a_owner) ? i_ack : 1'b0; |
|
// Stall must be asserted on the same cycle the input master asserts |
// the bus, if the bus isn't granted to him. |
assign o_a_stall = ( r_a_owner) ? i_stall : 1'b1; |
assign o_b_stall = (~r_a_owner) ? i_stall : 1'b1; |
|
// |
// These error lines will be implemented soon, as soon as the rest of |
// the Zip CPU is ready to support them. |
// |
assign o_a_err = ( r_a_owner) ? i_err : 1'b0; |
assign o_b_err = (~r_a_owner) ? i_err : 1'b0; |
|
endmodule |
|