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 38 to Rev 48
- ↔ Reverse comparison
Rev 38 → Rev 48
/core/pipemem.v
File deleted
/core/memops.v
44,6 → 44,7
o_wb_stb_gbl, o_wb_stb_lcl, |
o_wb_we, o_wb_addr, o_wb_data, |
i_wb_ack, i_wb_stall, i_wb_err, i_wb_data); |
parameter ADDRESS_WIDTH=24, AW=ADDRESS_WIDTH; |
input i_clk, i_rst; |
input i_stb; |
// CPU interface |
60,7 → 61,8
// Wishbone outputs |
output reg o_wb_cyc_gbl, o_wb_stb_gbl; |
output reg o_wb_cyc_lcl, o_wb_stb_lcl, o_wb_we; |
output reg [31:0] o_wb_addr, o_wb_data; |
output reg [(AW-1):0] o_wb_addr; |
output reg [31:0] o_wb_data; |
// Wishbone inputs |
input i_wb_ack, i_wb_stall, i_wb_err; |
input [31:0] i_wb_data; |
101,7 → 103,7
begin |
o_wb_we <= i_op; |
o_wb_data <= i_data; |
o_wb_addr <= i_addr; |
o_wb_addr <= i_addr[(AW-1):0]; |
end |
|
initial o_valid = 1'b0; |
/core/prefetch.v
51,19 → 51,19
o_i, o_pc, o_aux, o_valid, o_illegal, |
o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, |
i_wb_ack, i_wb_stall, i_wb_err, i_wb_data); |
parameter AW = 1; |
input i_clk, i_rst, i_ce; |
input [31:0] i_pc; |
input [(AW-1):0] i_aux; |
output reg [31:0] o_i; |
output reg [31:0] o_pc; |
output reg [(AW-1):0] o_aux; |
output wire o_valid, o_illegal; |
parameter ADDRESS_WIDTH=32, AUX_WIDTH = 1, AW=ADDRESS_WIDTH; |
input i_clk, i_rst, i_ce; |
input [(AW-1):0] i_pc; |
input [(AUX_WIDTH-1):0] i_aux; |
output reg [31:0] o_i; |
output reg [(AW-1):0] o_pc; |
output reg [(AUX_WIDTH-1):0] o_aux; |
output wire o_valid, o_illegal; |
// Wishbone outputs |
output reg o_wb_cyc, o_wb_stb; |
output wire o_wb_we; |
output reg [31:0] o_wb_addr; |
output wire [31:0] o_wb_data; |
output reg o_wb_cyc, o_wb_stb; |
output wire o_wb_we; |
output reg [(AW-1):0] o_wb_addr; |
output wire [31:0] o_wb_data; |
// And return inputs |
input i_wb_ack, i_wb_stall, i_wb_err; |
input [31:0] i_wb_data; |
/core/pipefetch.v
54,18 → 54,18
i_wb_ack, i_wb_stall, i_wb_err, i_wb_data, i_wb_request, |
o_illegal); |
parameter RESET_ADDRESS=32'h0010_0000, |
LGCACHELEN = 6, CACHELEN=(1<<LGCACHELEN), |
BUSW=32; |
LGCACHELEN = 6, ADDRESS_WIDTH=24, |
CACHELEN=(1<<LGCACHELEN), BUSW=32, AW=ADDRESS_WIDTH; |
input i_clk, i_rst, i_new_pc, |
i_clear_cache, i_stall_n; |
input [(BUSW-1):0] i_pc; |
input [(AW-1):0] i_pc; |
output reg [(BUSW-1):0] o_i; |
output reg [(BUSW-1):0] o_pc; |
output reg [(AW-1):0] o_pc; |
output wire o_v; |
// |
output reg o_wb_cyc, o_wb_stb; |
output wire o_wb_we; |
output reg [(BUSW-1):0] o_wb_addr; |
output reg [(AW-1):0] o_wb_addr; |
output wire [(BUSW-1):0] o_wb_data; |
// |
input i_wb_ack, i_wb_stall, i_wb_err; |
83,7 → 83,7
assign o_wb_we = 1'b0; |
assign o_wb_data = 0; |
|
reg [(BUSW-1):0] r_cache_base; |
reg [(AW-1):0] r_cache_base; |
reg [(LGCACHELEN):0] r_nvalid, r_acks_waiting; |
reg [(BUSW-1):0] cache[0:(CACHELEN-1)]; |
|
90,10 → 90,10
reg [(LGCACHELEN-1):0] r_cache_offset; |
|
reg r_addr_set; |
reg [(BUSW-1):0] r_addr; |
reg [(AW-1):0] r_addr; |
|
wire [(BUSW-1):0] bus_nvalid; |
assign bus_nvalid = { {(BUSW-LGCACHELEN-1){1'b0}}, r_nvalid }; |
wire [(AW-1):0] bus_nvalid; |
assign bus_nvalid = { {(AW-LGCACHELEN-1){1'b0}}, r_nvalid }; |
|
// What are some of the conditions for which we need to restart the |
// cache? |
100,14 → 100,18
wire w_pc_out_of_bounds; |
assign w_pc_out_of_bounds = ((i_new_pc)&&((r_nvalid == 0) |
||(i_pc < r_cache_base) |
||(i_pc >= r_cache_base + CACHELEN))); |
||(i_pc >= r_cache_base + CACHELEN) |
||(i_pc >= r_cache_base + bus_nvalid+5))); |
wire w_ran_off_end_of_cache; |
assign w_ran_off_end_of_cache =((r_addr_set)&&((r_addr < r_cache_base) |
||(r_addr >= r_cache_base + CACHELEN))); |
||(r_addr >= r_cache_base + CACHELEN) |
||(r_addr >= r_cache_base + bus_nvalid+5))); |
wire w_running_out_of_cache; |
assign w_running_out_of_cache = (r_addr_set) |
&&(r_addr >= r_cache_base + (1<<(LGCACHELEN-2)) |
+ (1<<(LGCACHELEN-1))); |
+ (1<<(LGCACHELEN-1))) |
&&(|r_nvalid[(LGCACHELEN):(LGCACHELEN-1)]); |
|
initial r_cache_base = RESET_ADDRESS; |
always @(posedge i_clk) |
begin |
/core/zipcpu.v
132,10 → 132,14
// `define OPT_SINGLE_FETCH |
// (Best path--define these!) |
`define OPT_CONDITIONAL_FLAGS |
`define OPT_ILLEGAL_INSTRUCTION |
`ifndef OPT_SINGLE_FETCH |
// The following are pipeline optimization options. |
// They make no sense in a single instruction fetch mode. |
`define OPT_PRECLEAR_BUS |
`define OPT_ILLEGAL_INSTRUCTION |
`define OPT_EARLY_BRANCHING |
`define OPT_PIPELINED_BUS_ACCESS |
`endif |
module zipcpu(i_clk, i_rst, i_interrupt, |
// Debug interface |
i_halt, i_clear_pf_cache, i_dbg_reg, i_dbg_we, i_dbg_data, |
149,7 → 153,8
i_wb_err, |
// Accounting/CPU usage interface |
o_op_stall, o_pf_stall, o_i_count); |
parameter RESET_ADDRESS=32'h0100000, LGICACHE=9; |
parameter RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=24, |
LGICACHE=6, AW=ADDRESS_WIDTH; |
input i_clk, i_rst, i_interrupt; |
// Debug interface -- inputs |
input i_halt, i_clear_pf_cache; |
164,7 → 169,8
// Wishbone interface -- outputs |
output wire o_wb_gbl_cyc, o_wb_gbl_stb; |
output wire o_wb_lcl_cyc, o_wb_lcl_stb, o_wb_we; |
output wire [31:0] o_wb_addr, o_wb_data; |
output wire [(AW-1):0] o_wb_addr; |
output wire [31:0] o_wb_data; |
// Wishbone interface -- inputs |
input i_wb_ack, i_wb_stall; |
input [31:0] i_wb_data; |
197,7 → 203,7
// PIPELINE STAGE #1 :: Prefetch |
// Variable declarations |
// |
reg [31:0] pf_pc; |
reg [(AW-1):0] pf_pc; |
reg new_pc, op_break; |
wire clear_pipeline; |
assign clear_pipeline = new_pc || i_clear_pf_cache; // || op_break; |
204,8 → 210,10
|
wire dcd_stalled; |
wire pf_cyc, pf_stb, pf_we, pf_busy, pf_ack, pf_stall, pf_err; |
wire [31:0] pf_addr, pf_data; |
wire [31:0] instruction, instruction_pc; |
wire [(AW-1):0] pf_addr; |
wire [31:0] pf_data; |
wire [31:0] instruction; |
wire [(AW-1):0] instruction_pc; |
wire pf_valid, instruction_gie, pf_illegal; |
|
// |
222,8 → 230,9
reg [3:0] dcdF; |
reg dcdA_rd, dcdA_wr, dcdB_rd, dcdvalid, |
dcdM, dcdF_wr, dcd_gie, dcd_break; |
reg [31:0] dcd_pc; |
reg [(AW-1):0] dcd_pc; |
reg [23:0] r_dcdI; |
reg dcd_zI; // true if dcdI == 0 |
wire dcdA_stall, dcdB_stall, dcdF_stall; |
|
`ifdef OPT_PRECLEAR_BUS |
233,11 → 242,11
reg dcd_illegal; |
`endif |
`ifdef OPT_EARLY_BRANCHING |
reg dcd_early_branch_stb, dcd_early_branch; |
reg [31:0] dcd_branch_pc; |
reg dcd_early_branch_stb, dcd_early_branch; |
reg [(AW-1):0] dcd_branch_pc; |
`else |
wire dcd_early_branch_stb, dcd_early_branch; |
wire [31:0] dcd_branch_pc; |
wire dcd_early_branch_stb, dcd_early_branch; |
wire [(AW-1):0] dcd_branch_pc; |
`endif |
|
|
252,7 → 261,8
reg [4:0] alu_reg; |
reg [3:0] opn; |
reg [4:0] opR; |
reg [31:0] r_opA, r_opB, op_pc; |
reg [31:0] r_opA, r_opB; |
reg [(AW-1):0] op_pc; |
wire [31:0] w_opA, w_opB; |
wire [31:0] opA_nowait, opB_nowait, opA, opB; |
reg opR_wr, opR_cc, opF_wr, op_gie, |
275,7 → 285,7
// Variable declarations |
// |
// |
reg [31:0] alu_pc; |
reg [(AW-1):0] alu_pc; |
reg alu_pc_valid;; |
wire alu_ce, alu_stall; |
wire [31:0] alu_result; |
297,10 → 307,12
`endif |
wire mem_valid, mem_ack, mem_stall, mem_err, bus_err, |
mem_cyc_gbl, mem_cyc_lcl, mem_stb_gbl, mem_stb_lcl, mem_we; |
wire [4:0] mem_wreg; |
wire [4:0] mem_wreg; |
|
wire mem_busy, mem_rdbusy; |
wire [31:0] mem_addr, mem_data, mem_result; |
wire mem_busy, mem_rdbusy; |
wire [(AW-1):0] mem_addr; |
wire [31:0] mem_data, mem_result; |
reg [4:0] mem_last_reg; // Last register result to go in |
|
|
|
313,7 → 325,7
wire [4:0] wr_reg_id; |
wire [31:0] wr_reg_vl; |
wire w_switch_to_interrupt, w_release_from_interrupt; |
reg [31:0] upc, ipc; |
reg [(AW-1):0] upc, ipc; |
|
|
|
396,13 → 408,14
wire pf_ce; |
|
assign pf_ce = (~dcd_stalled); |
prefetch pf(i_clk, i_rst, (pf_ce), pf_pc, gie, |
prefetch #(ADDRESS_WIDTH) |
pf(i_clk, i_rst, (pf_ce), pf_pc, gie, |
instruction, instruction_pc, instruction_gie, |
pf_valid, pf_illegal, |
pf_cyc, pf_stb, pf_we, pf_addr, pf_data, |
pf_ack, pf_stall, pf_err, i_wb_data); |
`else // Pipe fetch |
pipefetch #(RESET_ADDRESS, LGICACHE) |
pipefetch #(RESET_ADDRESS, LGICACHE, ADDRESS_WIDTH) |
pf(i_clk, i_rst, (new_pc)|(dcd_early_branch_stb), |
i_clear_pf_cache, ~dcd_stalled, |
(new_pc)?pf_pc:dcd_branch_pc, |
467,16 → 480,16
if (dcd_ce) |
begin |
if (instruction[31]) // Add |
dcd_branch_pc <= instruction_pc+32'h01+{ {(12){instruction[19]}}, instruction[19:0] }; |
dcd_branch_pc <= instruction_pc+{ {(AW-20){instruction[19]}}, instruction[19:0] } + {{(AW-1){1'b0}},1'b1}; |
else if (~instruction[28]) // 4'h2 = MOV |
dcd_branch_pc <= instruction_pc+32'h01+{ {(17){instruction[14]}}, instruction[14:0] }; |
dcd_branch_pc <= instruction_pc+{ {(AW-15){instruction[14]}}, instruction[14:0] } + {{(AW-1){1'b0}},1'b1}; |
else // if (instruction[28]) // 4'h3 = LDI |
dcd_branch_pc <= instruction_pc+32'h01+{ {(8){instruction[23]}}, instruction[23:0] }; |
dcd_branch_pc <= instruction_pc+{ {(AW-24){instruction[23]}}, instruction[23:0] } + {{(AW-1){1'b0}},1'b1}; |
end |
`else // OPT_EARLY_BRANCHING |
assign dcd_early_branch_stb = 1'b0; |
assign dcd_early_branch = 1'b0; |
assign dcd_branch_pc = 32'h00; |
assign dcd_branch_pc = {(AW){1'b0}}; |
`endif // OPT_EARLY_BRANCHING |
|
always @(posedge i_clk) |
522,6 → 535,7
dcdA_rd <= 1'b0; |
dcdB_rd <= 1'b1; |
r_dcdI <= { {(9){instruction[14]}}, instruction[14:0] }; |
dcd_zI <= (instruction[14:0] == 0); |
dcdF_wr <= 1'b0; // Don't write flags |
end |
4'h3: begin // Load immediate |
529,6 → 543,7
dcdA_rd <= 1'b0; |
dcdB_rd <= 1'b0; |
r_dcdI <= { instruction[23:0] }; |
dcd_zI <= (instruction[23:0] == 0); |
dcdF_wr <= 1'b0; // Don't write flags |
dcdF <= 4'h8; // This is unconditional |
dcdOp <= 4'h2; |
544,6 → 559,7
dcdF_wr <= (instruction[27:25] != 3'h7); |
`endif |
r_dcdI <= { 8'h00, instruction[15:0] }; |
dcd_zI <= (instruction[15:0] == 0); |
if (instruction[27:24] == 4'he) |
begin |
// NOOP instruction |
568,6 → 584,7
end else begin |
// Actual multiply instruction |
r_dcdI <= { 8'h00, instruction[15:0] }; |
dcd_zI <= (instruction[15:0] == 0); |
dcdA_rd <= 1'b1; |
dcdB_rd <= (instruction[19:16] != 4'hf); |
dcdOp[3:0] <= (instruction[20])? 4'h4:4'h3; |
578,9 → 595,13
dcdA_rd <= (instruction[28]); // Read on stores |
dcdB_rd <= instruction[20]; |
if (instruction[20]) |
begin |
r_dcdI <= { {(8){instruction[15]}}, instruction[15:0] }; |
else |
dcd_zI <= (instruction[15:0] == 0); |
end else begin |
r_dcdI <= { {(4){instruction[19]}}, instruction[19:0] }; |
dcd_zI <= (instruction[19:0] == 0); |
end |
dcdM <= 1'b1; // Memory operation |
`ifdef OPT_PRECLEAR_BUS |
dcd_clear_bus <= (instruction[23:21]==3'h0); |
591,10 → 612,13
dcdA_rd <= 1'b1; |
dcdB_rd <= instruction[20]; |
if (instruction[20]) |
begin |
r_dcdI <= { {(8){instruction[15]}}, instruction[15:0] }; |
else |
dcd_zI <= (instruction[15:0] == 0); |
end else begin |
r_dcdI <= { {(4){instruction[19]}}, instruction[19:0] }; |
end |
dcd_zI <= (instruction[19:0] == 0); |
end end |
endcase |
|
|
645,25 → 669,33
if ((wr_reg_ce)&&(wr_reg_id == dcdA)) |
r_opA <= wr_reg_vl; |
else if ((dcdA_pc)&&(dcdA[4] == dcd_gie)) |
r_opA <= dcd_pc; |
r_opA <= { {(32-AW){1'b0}}, dcd_pc }; |
else if (dcdA_pc) |
r_opA <= upc; |
r_opA <= { {(32-AW){1'b0}}, upc }; |
else if (dcdA_cc) |
r_opA <= { w_opA[31:11], (dcd_gie)?w_uflags:w_iflags }; |
else |
r_opA <= w_opA; |
end else if (opvalid) |
begin // We were going to pick these up when they became valid, |
// but for some reason we're stuck here as they became |
// valid. Pick them up now anyway |
if ((opA_alu)||((opA_mem)&&(mem_valid))) |
r_opA <= wr_reg_vl; |
end |
wire [31:0] dcdI, w_opBnI; |
assign dcdI = { {(8){r_dcdI[23]}}, r_dcdI }; |
assign w_opBnI = (~dcdB_rd) ? 32'h00 |
: (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_reg_vl |
: (((dcdB_pc)&&(dcdB[4] == dcd_gie)) ? dcd_pc |
: ((dcdB_pc) ? upc |
: (((dcdB_pc)&&(dcdB[4] == dcd_gie)) ? {{(32-AW){1'b0}},dcd_pc } |
: ((dcdB_pc) ? {{(32-AW){1'b0}},upc} |
: ((dcdB_cc) ? { w_opB[31:11], (dcd_gie)?w_uflags:w_iflags} |
: regset[dcdB])))); |
always @(posedge i_clk) |
if (op_ce) // &&(dcdvalid)) |
r_opB <= w_opBnI + dcdI; |
else if ((opvalid)&&((opB_alu)||((opB_mem)&&(mem_valid)))) |
r_opB <= wr_reg_vl; |
|
// The logic here has become more complex than it should be, no thanks |
// to Xilinx's Vivado trying to help. The conditions are supposed to |
773,7 → 805,6
// use that value. |
opA_rd <= dcdA_rd; |
opB_rd <= dcdB_rd; |
op_pc <= dcd_pc; |
// |
`ifdef OPT_EARLY_BRANCHING |
op_wr_pc <= ((dcdA_wr)&&(dcdA_pc)&&(dcdA[4] == dcd_gie))&&(~dcd_early_branch); |
780,6 → 811,8
`else |
op_wr_pc <= ((dcdA_wr)&&(dcdA_pc)&&(dcdA[4] == dcd_gie)); |
`endif |
op_pc <= (dcd_early_branch)?dcd_branch_pc:dcd_pc; |
// op_pc <= dcd_pc; |
|
`ifdef OPT_PRECLEAR_BUS |
op_clear_bus <= dcd_clear_bus; |
799,25 → 832,51
// We'll create a flag here to start our coordination. Once we |
// define this flag to something other than just plain zero, then |
// the stalls will already be in place. |
reg opA_alu; |
reg opA_alu, opA_mem; |
always @(posedge i_clk) |
if (op_ce) |
opA_alu <= (opvalid_alu)&&(opR == dcdA)&&(dcdA_rd); |
assign opA = (opA_alu) ? alu_result : r_opA; |
opA_alu <= (opvalid_alu)&&(opR == dcdA)&&(opR_wr)&&(dcdA_rd); |
else if ((opvalid)&&(opA_alu)&&(alu_valid)) |
opA_alu <= 1'b0; |
always @(posedge i_clk) |
if (op_ce) |
opA_mem <= ((opvalid_mem)&&(opR == dcdA)&&(dcdA_rd)) |
||((~opvalid)&&(mem_busy)&&(~mem_we) |
&&(mem_last_reg == dcdA)&&(dcdA_rd)); |
else if ((opvalid)&&(opA_mem)&&(mem_valid)) |
opA_mem <= 1'b0; |
|
always @(posedge i_clk) |
if (mem_ce) |
mem_last_reg <= opR; |
assign opA = (opA_alu) ? alu_result |
: ( ((opA_mem)&&(mem_valid))?mem_result |
: r_opA ); |
|
assign dcdA_stall = (dcdvalid)&&(dcdA_rd)&&( |
// Skip the requirement on writing back opA |
// Stall on memory, since we'll always need to stall for a |
// memory access anyway |
((opvalid_mem)&&(opR_wr)&&(opR == dcdA))|| |
((opvalid_alu)&&(opF_wr)&&(dcdA_cc))|| |
((mem_busy)&&(~mem_we)&&(mem_wreg == dcdA))); |
// ((opvalid_mem)&&(opR_wr)&&(opR == dcdA)) |
((opvalid_alu)&&(opF_wr)&&(dcdA_cc))); |
// Place stalls for this latter case into the ops stage |
// ||((mem_busy)&&(~mem_we)); |
|
reg opB_alu; |
reg opB_alu, opB_mem; |
always @(posedge i_clk) |
if (op_ce) |
opB_alu <= (opvalid_alu)&&(opR == dcdB)&&(dcdB_rd)&&(dcdI == 0); |
assign opB = (opB_alu) ? alu_result : r_opB; |
opB_alu <= (opvalid_alu)&&(opR == dcdB)&&(opR_wr)&&(dcdB_rd)&&(dcd_zI); |
always @(posedge i_clk) |
if (op_ce) |
opB_mem <= (dcd_zI)&&(dcdB_rd)&&( |
((opvalid_mem)&&(opR == dcdB)) |
||((~opvalid)&&(mem_busy)&&(~mem_we) |
&&(mem_last_reg == dcdB))); |
else if ((opvalid)&&(opB_mem)&&(mem_valid)) |
opB_mem <= 1'b0; |
assign opB = (opB_alu) ? alu_result |
: ( ((opB_mem)&&(mem_valid))?mem_result |
: r_opB ); |
assign dcdB_stall = (dcdvalid)&&(dcdB_rd)&&( |
// Stall on memory ops writing to my register |
// (i.e. loads), or on any write to my |
830,7 → 889,7
// here. |
((opvalid)&&(opR_wr)&&(opR == dcdB) |
&&(opR != { op_gie, `CPU_PC_REG} ) |
&&((opvalid_mem)||(dcdI != 0))) |
&&(~dcd_zI)) |
// Stall on any write to the flags register, |
// if we're going to need the flags value for |
// opB. |
837,7 → 896,7
||((opvalid_alu)&&(opF_wr)&&(dcdB_cc)) |
// Stall on any ongoing memory operation that |
// will write to opB |
||((mem_busy)&&(~mem_we)&&(mem_wreg == dcdB))); |
||((mem_busy)&&(~mem_we)&&(mem_last_reg==dcdB))); |
assign dcdF_stall = (dcdvalid)&&((~dcdF[3])||(dcdA_cc)||(dcdB_cc)) |
&&(opvalid)&&(opR_cc); |
// |
886,7 → 945,7
&&((opvalid_alu)||(~mem_stalled)); |
|
`ifdef OPT_PIPELINED_BUS_ACCESS |
pipemem domem(i_clk, i_rst, mem_ce, |
pipemem #(AW) domem(i_clk, i_rst, mem_ce, |
(opn[0]), opB, opA, opR, |
mem_busy, mem_pipe_stalled, |
mem_valid, bus_err, mem_wreg, mem_result, |
896,7 → 955,7
mem_ack, mem_stall, mem_err, i_wb_data); |
|
`else // PIPELINED_BUS_ACCESS |
memops domem(i_clk, i_rst, mem_ce, |
memops #(AW) domem(i_clk, i_rst, mem_ce, |
(opn[0]), opB, opA, opR, |
mem_busy, |
mem_valid, bus_err, mem_wreg, mem_result, |
909,7 → 968,7
|
// Either the prefetch or the instruction gets the memory bus, but |
// never both. |
wbdblpriarb #(32,32) pformem(i_clk, i_rst, |
wbdblpriarb #(32,AW) pformem(i_clk, i_rst, |
// Memory access to the arbiter, priority position |
mem_cyc_gbl, mem_cyc_lcl, mem_stb_gbl, mem_stb_lcl, |
mem_we, mem_addr, mem_data, mem_ack, mem_stall, mem_err, |
1147,23 → 1206,23
// a non-gie instruction? |
always @(posedge i_clk) |
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc)) |
upc <= wr_reg_vl; |
upc <= wr_reg_vl[(AW-1):0]; |
else if ((alu_gie)&&(alu_pc_valid)&&(~clear_pipeline)) |
upc <= alu_pc; |
else if ((i_halt)&&(i_dbg_we) |
&&(i_dbg_reg == { 1'b1, `CPU_PC_REG })) |
upc <= i_dbg_data; |
upc <= i_dbg_data[(AW-1):0]; |
|
always @(posedge i_clk) |
if (i_rst) |
ipc <= RESET_ADDRESS; |
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_pc)) |
ipc <= wr_reg_vl; |
ipc <= wr_reg_vl[(AW-1):0]; |
else if ((~alu_gie)&&(alu_pc_valid)&&(~clear_pipeline)) |
ipc <= alu_pc; |
else if ((i_halt)&&(i_dbg_we) |
&&(i_dbg_reg == { 1'b0, `CPU_PC_REG })) |
ipc <= i_dbg_data; |
ipc <= i_dbg_data[(AW-1):0]; |
|
always @(posedge i_clk) |
if (i_rst) |
1173,10 → 1232,10
else if (w_release_from_interrupt) |
pf_pc <= upc; |
else if ((wr_reg_ce)&&(wr_reg_id[4] == gie)&&(wr_write_pc)) |
pf_pc <= wr_reg_vl; |
pf_pc <= wr_reg_vl[(AW-1):0]; |
else if ((i_halt)&&(i_dbg_we) |
&&(i_dbg_reg[4:0] == { gie, `CPU_PC_REG})) |
pf_pc <= i_dbg_data; |
pf_pc <= i_dbg_data[(AW-1):0]; |
else if (dcd_ce) |
pf_pc <= pf_pc + 1; |
|
1202,7 → 1261,7
begin |
o_dbg_reg <= regset[i_dbg_reg]; |
if (i_dbg_reg[3:0] == `CPU_PC_REG) |
o_dbg_reg <= (i_dbg_reg[4])?upc:ipc; |
o_dbg_reg <= {{(32-AW){1'b0}},(i_dbg_reg[4])?upc:ipc}; |
else if (i_dbg_reg[3:0] == `CPU_CC_REG) |
o_dbg_reg[10:0] <= (i_dbg_reg[4])?w_uflags:w_iflags; |
end |
/zipsystem.v
162,12 → 162,14
// Wishbone slave interface for debugging purposes |
i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr, i_dbg_data, |
o_dbg_ack, o_dbg_stall, o_dbg_data); |
parameter RESET_ADDRESS=32'h0100000, START_HALTED=1, |
EXTERNAL_INTERRUPTS=1; |
parameter RESET_ADDRESS=24'h0100000, ADDRESS_WIDTH=24, |
LGICACHE=6, START_HALTED=1, EXTERNAL_INTERRUPTS=1, |
// Derived parameters |
AW=ADDRESS_WIDTH; |
input i_clk, i_rst; |
// Wishbone master |
output wire o_wb_cyc, o_wb_stb, o_wb_we; |
output wire [31:0] o_wb_addr; |
output wire [(AW-1):0] o_wb_addr; |
output wire [31:0] o_wb_data; |
input i_wb_ack, i_wb_stall; |
input [31:0] i_wb_data; |
213,7 → 215,7
// |
wire sys_cyc, sys_stb, sys_we; |
wire [4:0] sys_addr; |
wire [31:0] cpu_addr; |
wire [(AW-1):0] cpu_addr; |
wire [31:0] sys_data; |
wire sys_ack, sys_stall; |
|
443,10 → 445,11
wire [31:0] dmac_data; |
wire dmac_ack, dmac_stall; |
wire dc_cyc, dc_stb, dc_we, dc_ack, dc_stall; |
wire [31:0] dc_data, dc_addr; |
wire [31:0] dc_data; |
wire [(AW-1):0] dc_addr; |
wire cpu_gbl_cyc; |
assign dmac_stb = (sys_stb)&&(sys_addr[4]); |
wbdmac dma_controller(i_clk, |
wbdmac #(AW) dma_controller(i_clk, |
sys_cyc, dmac_stb, sys_we, |
sys_addr[1:0], sys_data, |
dmac_ack, dmac_stall, dmac_data, |
558,7 → 561,8
wire [31:0] cpu_dbg_data; |
assign cpu_dbg_we = ((dbg_cyc)&&(dbg_stb)&&(~cmd_addr[5]) |
&&(dbg_we)&&(dbg_addr)); |
zipcpu #(RESET_ADDRESS) thecpu(i_clk, cpu_reset, pic_interrupt, |
zipcpu #(RESET_ADDRESS,ADDRESS_WIDTH,LGICACHE) |
thecpu(i_clk, cpu_reset, pic_interrupt, |
cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we, |
dbg_idata, cpu_dbg_stall, cpu_dbg_data, |
cpu_dbg_cc, cpu_break, |
612,8 → 616,9
wire ext_cyc, ext_stb, ext_we, ext_err; |
wire cpu_ext_ack, cpu_ext_stall, ext_ack, ext_stall, |
cpu_ext_err; |
wire [31:0] ext_addr, ext_odata; |
wbpriarbiter #(32,32) dmacvcpu(i_clk, i_rst, |
wire [(AW-1):0] ext_addr; |
wire [31:0] ext_odata; |
wbpriarbiter #(32,AW) dmacvcpu(i_clk, i_rst, |
cpu_gbl_cyc, cpu_gbl_stb, cpu_we, cpu_addr, cpu_data, |
cpu_ext_ack, cpu_ext_stall, cpu_ext_err, |
dc_cyc, dc_stb, dc_we, dc_addr, dc_data, |
622,7 → 627,7
ext_ack, ext_stall, ext_err); |
|
`ifdef DELAY_EXT_BUS |
busdelay #(32,32) extbus(i_clk, |
busdelay #(AW,32) extbus(i_clk, |
ext_cyc, ext_stb, ext_we, ext_addr, ext_odata, |
ext_ack, ext_stall, ext_idata, ext_err, |
o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, |
/zipbones.v
42,18 → 42,19
// Wishbone slave interface for debugging purposes |
i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr, i_dbg_data, |
o_dbg_ack, o_dbg_stall, o_dbg_data); |
parameter RESET_ADDRESS=32'h0100000, START_HALTED=1, |
EXTERNAL_INTERRUPTS=1; |
parameter RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=32, |
LGICACHE=6, START_HALTED=1, |
AW=ADDRESS_WIDTH; |
input i_clk, i_rst; |
// Wishbone master |
output wire o_wb_cyc, o_wb_stb, o_wb_we; |
output wire [31:0] o_wb_addr; |
output wire [(AW-1):0] o_wb_addr; |
output wire [31:0] o_wb_data; |
input i_wb_ack, i_wb_stall; |
input [31:0] i_wb_data; |
input i_wb_err; |
// Incoming interrupts |
input [(EXTERNAL_INTERRUPTS-1):0] i_ext_int; |
input i_ext_int; |
// Outgoing interrupt |
output wire o_ext_int; |
// Wishbone slave |
68,7 → 69,7
// |
wire sys_cyc, sys_stb, sys_we; |
wire [4:0] sys_addr; |
wire [31:0] cpu_addr; |
wire [(AW-1):0] cpu_addr; |
wire [31:0] sys_data; |
wire sys_ack, sys_stall; |
|
138,7 → 139,7
// 0x01000 -> cc.sleep |
// 0x02000 -> cc.gie |
// 0x10000 -> External interrupt line is high |
assign cmd_data = { 7'h00, {(9-EXTERNAL_INTERRUPTS){1'b0}}, i_ext_int, |
assign cmd_data = { 7'h00, 8'h00, i_ext_int, |
2'b00, cpu_dbg_cc, |
1'b0, cmd_halt, (~cpu_dbg_stall), 1'b0, |
pic_data[15], cpu_reset, 1'b0, cmd_addr }; |
156,7 → 157,8
wire [31:0] cpu_dbg_data; |
assign cpu_dbg_we = ((i_dbg_cyc)&&(i_dbg_stb) |
&&(i_dbg_we)&&(i_dbg_addr)); |
zipcpu #(RESET_ADDRESS) thecpu(i_clk, cpu_reset, i_ext_int, |
zipcpu #(RESET_ADDRESS,ADDRESS_WIDTH,LGICACHE) |
thecpu(i_clk, cpu_reset, i_ext_int, |
cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we, |
i_dbg_data, cpu_dbg_stall, cpu_dbg_data, |
cpu_dbg_cc, cpu_break, |
/peripherals/zipport.v
File deleted
/peripherals/wbdmac.v
113,7 → 113,8
i_dev_ints, |
o_interrupt, |
i_other_busmaster_requests_bus); |
parameter LGMEMLEN = 10, DW=32, LGDV=5; |
parameter ADDRESS_WIDTH=32, LGMEMLEN = 10, |
DW=32, LGDV=5,AW=ADDRESS_WIDTH; |
input i_clk; |
// Slave/control wishbone inputs |
input i_swb_cyc, i_swb_stb, i_swb_we; |
125,7 → 126,8
output reg [(DW-1):0] o_swb_data; |
// Master/DMA wishbone control |
output reg o_mwb_cyc, o_mwb_stb, o_mwb_we; |
output reg [(DW-1):0] o_mwb_addr, o_mwb_data; |
output reg [(AW-1):0] o_mwb_addr; |
output reg [(DW-1):0] o_mwb_data; |
// Master/DMA wishbone responses from the bus |
input i_mwb_ack, i_mwb_stall; |
input [(DW-1):0] i_mwb_data; |
140,7 → 142,7
|
reg cfg_wp; // Write protect |
reg cfg_err; |
reg [(DW-1):0] cfg_waddr, cfg_raddr, cfg_len; |
reg [(AW-1):0] cfg_waddr, cfg_raddr, cfg_len; |
reg [(LGMEMLEN-1):0] cfg_blocklen_sub_one; |
reg cfg_incs, cfg_incd; |
reg [(LGDV-1):0] cfg_dev_trigger; |
151,14 → 153,14
|
reg [(DW-1):0] dma_mem [0:(((1<<LGMEMLEN))-1)]; |
reg [(LGMEMLEN):0] nread, nwritten, nacks; |
wire [(DW-1):0] bus_nacks; |
assign bus_nacks = { {(DW-LGMEMLEN-1){1'b0}}, nacks }; |
wire [(AW-1):0] bus_nacks; |
assign bus_nacks = { {(AW-LGMEMLEN-1){1'b0}}, nacks }; |
|
initial o_interrupt = 1'b0; |
initial o_mwb_cyc = 1'b0; |
initial cfg_err = 1'b0; |
initial cfg_wp = 1'b0; |
initial cfg_len = 32'h00; |
initial cfg_len = {(AW){1'b0}}; |
initial cfg_blocklen_sub_one = {(LGMEMLEN){1'b1}}; |
initial cfg_on_dev_trigger = 1'b0; |
always @(posedge i_clk) |
271,9 → 273,9
cfg_incd <= ~i_swb_data[28]; |
cfg_err <= 1'b0; |
end |
2'b01: cfg_len <= i_swb_data; |
2'b10: cfg_raddr <= i_swb_data; |
2'b11: cfg_waddr <= i_swb_data; |
2'b01: cfg_len <= i_swb_data[(AW-1):0]; |
2'b10: cfg_raddr <= i_swb_data[(AW-1):0]; |
2'b11: cfg_waddr <= i_swb_data[(AW-1):0]; |
endcase |
end |
end |
311,9 → 313,9
cfg_on_dev_trigger, cfg_dev_trigger, |
cfg_blocklen_sub_one |
}; |
2'b01: o_swb_data <= cfg_len; |
2'b10: o_swb_data <= cfg_raddr; |
2'b11: o_swb_data <= cfg_waddr; |
2'b01: o_swb_data <= { {(DW-AW){1'b0}}, cfg_len }; |
2'b10: o_swb_data <= { {(DW-AW){1'b0}}, cfg_raddr}; |
2'b11: o_swb_data <= { {(DW-AW){1'b0}}, cfg_waddr}; |
endcase |
|
always @(posedge i_clk) |