OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 47 to Rev 48
    Reverse comparison

Rev 47 → Rev 48

/zipcpu/trunk/rtl/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;
/zipcpu/trunk/rtl/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;
/zipcpu/trunk/rtl/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
/zipcpu/trunk/rtl/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
/zipcpu/trunk/rtl/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,
/zipcpu/trunk/rtl/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,
/zipcpu/trunk/rtl/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)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.