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 195 to Rev 201
- ↔ Reverse comparison
Rev 195 → Rev 201
/busdelay.v
37,7 → 37,7
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// Copyright (C) 2015-2017, 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 |
49,6 → 49,11
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory. Run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
55,12 → 60,13
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module busdelay(i_clk, |
// The input bus |
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, i_wb_sel, |
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, |
o_dly_cyc, o_dly_stb, o_dly_we, o_dly_addr,o_dly_data,o_dly_sel, |
i_dly_ack, i_dly_stall, i_dly_data, i_dly_err); |
parameter AW=32, DW=32, DELAY_STALL = 0; |
input i_clk; |
68,6 → 74,7
input i_wb_cyc, i_wb_stb, i_wb_we; |
input [(AW-1):0] i_wb_addr; |
input [(DW-1):0] i_wb_data; |
input [(DW/8-1):0] i_wb_sel; |
output reg o_wb_ack; |
output wire o_wb_stall; |
output reg [(DW-1):0] o_wb_data; |
76,6 → 83,7
output reg o_dly_cyc, o_dly_stb, o_dly_we; |
output reg [(AW-1):0] o_dly_addr; |
output reg [(DW-1):0] o_dly_data; |
output reg [(DW/8-1):0] o_dly_sel; |
input i_dly_ack; |
input i_dly_stall; |
input [(DW-1):0] i_dly_data; |
85,8 → 93,9
if (DELAY_STALL != 0) |
begin |
reg r_stb, r_we, r_rtn_stall, r_rtn_err; |
reg [(AW-1):0] r_addr; |
reg [(DW-1):0] r_data; |
reg [(AW-1):0] r_addr; |
reg [(DW/8-1):0] r_sel; |
|
initial o_dly_cyc = 1'b0; |
initial r_rtn_stall= 1'b0; |
100,6 → 109,7
r_we <= i_wb_we; |
r_addr <= i_wb_addr; |
r_data <= i_wb_data; |
r_sel <= i_wb_sel; |
|
if (r_stb) |
begin |
106,6 → 116,7
o_dly_we <= r_we; |
o_dly_addr <= r_addr; |
o_dly_data <= r_data; |
o_dly_sel <= r_sel; |
o_dly_stb <= 1'b1; |
r_rtn_stall <= 1'b0; |
r_stb <= 1'b0; |
113,6 → 124,7
o_dly_we <= i_wb_we; |
o_dly_addr <= i_wb_addr; |
o_dly_data <= i_wb_data; |
o_dly_sel <= i_wb_sel; |
o_dly_stb <= i_wb_stb; |
r_stb <= 1'b0; |
r_rtn_stall <= 1'b0; |
122,6 → 134,7
r_we <= i_wb_we; |
r_addr <= i_wb_addr; |
r_data <= i_wb_data; |
r_sel <= i_wb_sel; |
r_stb <= i_wb_stb; |
|
r_rtn_stall <= i_wb_stb; |
165,6 → 178,9
if (~o_wb_stall) |
o_dly_data <= i_wb_data; |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_sel <= i_wb_sel; |
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; |
/wbarbiter.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbarbiter.v |
// |
34,9 → 34,9
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015,2017, 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 |
48,20 → 48,26
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
`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, o_a_err, |
i_a_cyc, i_a_stb, i_a_we, i_a_adr, i_a_dat, i_a_sel, 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, o_b_err, |
i_b_cyc, i_b_stb, i_b_we, i_b_adr, i_b_dat, i_b_sel, 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, i_err); |
o_cyc, o_stb, o_we, o_adr, o_dat, o_sel, 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. |
71,6 → 77,7
input i_clk, i_rst; |
input [(AW-1):0] i_a_adr, i_b_adr; |
input [(DW-1):0] i_a_dat, i_b_dat; |
input [(DW/8-1):0] i_a_sel, i_b_sel; |
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, |
77,6 → 84,7
o_a_err, o_b_err; |
output wire [(AW-1):0] o_adr; |
output wire [(DW-1):0] o_dat; |
output wire [(DW/8-1):0] o_sel; |
output wire o_we, o_stb, o_cyc; |
input i_ack, i_stall, i_err; |
|
159,11 → 167,12
// 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. |
// irrelevant. (This allows us to get two outputs per Xilinx 6-LUT) |
assign o_stb = (o_cyc) && ((w_a_owner) ? i_a_stb : i_b_stb); |
assign o_we = (w_a_owner) ? i_a_we : i_b_we; |
assign o_adr = (w_a_owner) ? i_a_adr : i_b_adr; |
assign o_dat = (w_a_owner) ? i_a_dat : i_b_dat; |
assign o_we = (w_a_owner) ? i_a_we : i_b_we; |
assign o_stb = (o_cyc) && ((w_a_owner) ? i_a_stb : i_b_stb); |
assign o_sel = (w_a_owner) ? i_a_sel : i_b_sel; |
|
// We cannot allow the return acknowledgement to ever go high if |
// the master in question does not own the bus. Hence we force it |
/wbdblpriarb.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbdblpriarb.v |
// |
42,9 → 42,9
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015,2017, 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 |
56,19 → 56,25
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory. Run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
module wbdblpriarb(i_clk, i_rst, |
// |
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, |
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, i_a_sel, 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, |
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, i_b_sel, 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, |
o_cyc_a, o_cyc_b, o_stb_a, o_stb_b, o_we, o_adr, o_dat, o_sel, |
i_ack, i_stall, i_err); |
parameter DW=32, AW=32; |
// Wishbone doesn't use an i_ce signal. While it could, they dislike |
78,28 → 84,31
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; |
input [(DW/8-1):0] i_a_sel; |
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; |
input [(DW/8-1):0] i_b_sel; |
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; |
output wire [(DW/8-1):0] o_sel; |
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 |
// 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); |
assign o_cyc_a = ((r_a_owner) ? i_a_cyc_a : i_b_cyc_a); |
assign o_cyc_b = ((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) |
109,9 → 118,34
r_a_owner <= ((i_b_cyc_a)||(i_b_cyc_b))? 1'b0:1'b1; |
|
|
assign o_we = (r_a_owner) ? i_a_we : i_b_we; |
`ifdef ZERO_ON_IDLE |
// |
// ZERO_ON_IDLE uses more logic than the alternative. It should be |
// useful for reducing power, as these circuits tend to drive wires |
// all the way across the design, but it may also slow down the master |
// clock. I've used it as an option when using VERILATOR, 'cause |
// zeroing things on idle can make them stand out all the more when |
// staring at wires and dumps and such. |
// |
wire o_cyc, o_stb; |
assign o_cyc = ((o_cyc_a)||(o_cyc_b)); |
assign o_stb = (o_cyc)&&((o_stb_a)||(o_stb_b)); |
assign o_stb_a = (r_a_owner) ? (i_a_stb_a)&&(o_cyc_a) : (i_b_stb_a)&&(o_cyc_a); |
assign o_stb_b = (r_a_owner) ? (i_a_stb_b)&&(o_cyc_b) : (i_b_stb_b)&&(o_cyc_b); |
assign o_adr = ((o_stb_a)|(o_stb_b))?((r_a_owner) ? i_a_adr : i_b_adr):0; |
assign o_dat = (o_stb)?((r_a_owner) ? i_a_dat : i_b_dat):0; |
assign o_sel = (o_stb)?((r_a_owner) ? i_a_sel : i_b_sel):0; |
assign o_a_ack = (o_cyc)&&( r_a_owner) ? i_ack : 1'b0; |
assign o_b_ack = (o_cyc)&&(~r_a_owner) ? i_ack : 1'b0; |
assign o_a_stall = (o_cyc)&&( r_a_owner) ? i_stall : 1'b1; |
assign o_b_stall = (o_cyc)&&(~r_a_owner) ? i_stall : 1'b1; |
assign o_a_err = (o_cyc)&&( r_a_owner) ? i_err : 1'b0; |
assign o_b_err = (o_cyc)&&(~r_a_owner) ? i_err : 1'b0; |
`else |
// 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 |
// 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; |
119,6 → 153,7
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; |
assign o_sel = (r_a_owner) ? i_a_sel : i_b_sel; |
|
// We cannot allow the return acknowledgement to ever go high if |
// the master in question does not own the bus. Hence we force it |
137,6 → 172,7
// |
assign o_a_err = ( r_a_owner) ? i_err : 1'b0; |
assign o_b_err = (~r_a_owner) ? i_err : 1'b0; |
`endif |
|
endmodule |
|
/wbpriarbiter.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbpriarbiter.v |
// |
25,9 → 25,9
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015,2017, 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,19 → 39,25
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory. Run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
module wbpriarbiter(i_clk, |
// |
module wbpriarbiter(i_clk, |
// 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, |
i_a_cyc, i_a_stb, i_a_we, i_a_adr, i_a_dat, i_a_sel, 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, |
i_b_cyc, i_b_stb, i_b_we, i_b_adr, i_b_dat, i_b_sel, 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); |
o_cyc, o_stb, o_we, o_adr, o_dat, o_sel, i_ack, i_stall, i_err); |
parameter DW=32, AW=32; |
// |
input i_clk; |
59,16 → 65,19
input i_a_cyc, i_a_stb, i_a_we; |
input [(AW-1):0] i_a_adr; |
input [(DW-1):0] i_a_dat; |
input [(DW/8-1):0] i_a_sel; |
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; |
input [(DW/8-1):0] i_b_sel; |
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; |
output wire [(DW/8-1):0] o_sel; |
input i_ack, i_stall, i_err; |
|
// Go high immediately (new cycle) if ... |
89,13 → 98,34
|
// 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 |
// 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_we = (r_a_owner) ? i_a_we : i_b_we; |
`ifdef ZERO_ON_IDLE |
// |
// ZERO_ON_IDLE will use up more logic and may even slow down the master |
// clock if set. However, it may also reduce the power used by the |
// FPGA by preventing things from toggling when the bus isn't in use. |
// The option is here because it also makes it a lot easier to look |
// for when things happen on the bus via VERILATOR when timing and |
// logic counts don't matter. |
// |
assign o_stb = (o_cyc)?((r_a_owner) ? i_a_stb : i_b_stb):0; |
assign o_adr = (o_stb)?((r_a_owner) ? i_a_adr : i_b_adr):0; |
assign o_dat = (o_stb)?((r_a_owner) ? i_a_dat : i_b_dat):0; |
assign o_sel = (o_stb)?((r_a_owner) ? i_a_sel : i_b_sel):0; |
assign o_a_ack = (o_cyc)&&( r_a_owner) ? i_ack : 1'b0; |
assign o_b_ack = (o_cyc)&&(~r_a_owner) ? i_ack : 1'b0; |
assign o_a_stall = (o_cyc)&&( r_a_owner) ? i_stall : 1'b1; |
assign o_b_stall = (o_cyc)&&(~r_a_owner) ? i_stall : 1'b1; |
assign o_a_err = (o_cyc)&&( r_a_owner) ? i_err : 1'b0; |
assign o_b_err = (o_cyc)&&(~r_a_owner) ? i_err : 1'b0; |
`else |
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; |
assign o_sel = (r_a_owner) ? i_a_sel : i_b_sel; |
|
// We cannot allow the return acknowledgement to ever go high if |
// the master in question does not own the bus. Hence we force it |
108,10 → 138,11
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; |
`endif |
|
endmodule |
|