OpenCores
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 3 to Rev 9
    Reverse comparison

Rev 3 → Rev 9

/core/zipcpu.v
121,7 → 121,7
o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data,
i_wb_ack, i_wb_stall, i_wb_data,
// Accounting/CPU usage interface
o_mem_stall, o_pf_stall, o_alu_stall);
o_op_stall, o_pf_stall, o_i_count);
parameter RESET_ADDRESS=32'h0100000;
input i_clk, i_rst, i_interrupt;
// Debug interface -- inputs
140,30 → 140,31
input i_wb_ack, i_wb_stall;
input [31:0] i_wb_data;
// Accounting outputs ... to help us count stalls and usage
output wire o_mem_stall;
output wire o_op_stall;
output wire o_pf_stall;
output wire o_alu_stall;
output wire o_i_count;
 
// Registers
reg [31:0] regset [0:31];
 
// Condition codes
reg [3:0] flags, iflags; // (BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z
wire master_ce;
wire [7:0] w_uflags, w_iflags;
reg step, gie, sleep, break_en;
reg break_en, step, gie, sleep;
 
wire [4:0] mem_wreg;
wire mem_busy, mem_rdbusy;
// The master chip enable
wire master_ce;
 
reg [31:0] pf_pc;
reg new_pc;
 
//
//
// PIPELINE STAGE #1 :: Prefetch
// Variable declarations
//
wire pf_ce, dcd_stalled;
reg [31:0] pf_pc;
reg new_pc;
 
wire dcd_stalled;
wire pf_cyc, pf_stb, pf_we, pf_busy, pf_ack, pf_stall;
wire [31:0] pf_addr, pf_data;
wire [31:0] instruction, instruction_pc;
231,6 → 232,9
wire mem_ce, mem_stalled;
wire mem_valid, mem_ack, mem_stall,
mem_cyc, mem_stb, mem_we;
wire [4:0] mem_wreg;
 
wire mem_busy, mem_rdbusy;
wire [31:0] mem_addr, mem_data, mem_result;
 
 
257,7 → 261,6
//
// PIPELINE STAGE #1 :: Prefetch
// Calculate stall conditions
assign pf_ce = (~dcd_stalled);
 
//
// PIPELINE STAGE #2 :: Instruction Decode
300,6 → 303,9
//
//
`ifdef SINGLE_FETCH
wire pf_ce;
 
assign pf_ce = (~dcd_stalled);
prefetch pf(i_clk, i_rst, (pf_ce), pf_pc, gie,
instruction, instruction_pc, instruction_gie,
pf_valid,
790,9 → 796,7
// it? Do we clear both? What if a gie instruction tries to clear
// a non-gie instruction?
always @(posedge i_clk)
if (i_rst)
upc <= RESET_ADDRESS;
else if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc))
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc))
upc <= wr_reg_vl;
else if ((alu_gie)&&(alu_pc_valid))
upc <= alu_pc;
823,7 → 827,6
else if ((i_halt)&&(i_dbg_we)
&&(wr_reg_id[4:0] == { gie, `CPU_PC_REG}))
pf_pc <= i_dbg_data;
// else if (pf_ce)
else if (dcd_ce)
pf_pc <= pf_pc + 1;
 
865,11 → 868,7
// later evaluate how well we are doing.
//
//
assign o_mem_stall = (~i_halt)&&(~sleep)&&(opvalid)&&(mem_busy)
&&(~pf_cyc);
assign o_pf_stall = (~i_halt)&&(~sleep)&&(((pf_ce)&&(~pf_valid))
||((opvalid)&&(mem_busy)&&(pf_cyc)));
// assign o_alu_stall = (~i_halt)&&(~sleep)&&(~mem_busy)&&
// ((alu_stall)||(~alu_valid));
assign o_alu_stall = alu_pc_valid;
assign o_op_stall = (master_ce)&&((~opvalid)||(op_stall));
assign o_pf_stall = (master_ce)&&(~pf_valid);
assign o_i_count = alu_pc_valid;
endmodule
/zipsystem.v
194,32 → 194,32
// the CPU if not halted), then read/write the data from the data
// register.
//
wire cpu_break;
wire cpu_break, dbg_cmd_write;
reg cmd_reset, cmd_halt, cmd_step;
reg [5:0] cmd_addr;
assign dbg_cmd_write = (dbg_cyc)&&(dbg_stb)&&(dbg_we)&&(~dbg_addr);
//
initial cmd_reset = 1'b1;
always @(posedge i_clk)
cmd_reset <= ((dbg_cmd_write)&&(dbg_idata[6]));
//
initial cmd_halt = 1'b1;
initial cmd_step = 1'b0;
always @(posedge i_clk)
if (i_rst)
begin
cmd_halt <= 1'b0;
cmd_step <= 1'b0;
cmd_reset<= 1'b0;
cmd_addr <= 6'h00;
end else if ((dbg_cyc)&&(dbg_stb)
&&(dbg_we)&&(~dbg_addr))
begin
else if (dbg_cmd_write)
cmd_halt <= dbg_idata[10];
cmd_step <= dbg_idata[ 8];
cmd_reset<= dbg_idata[ 6];
else if ((cmd_step)||(cpu_break))
cmd_halt <= 1'b1;
//
initial cmd_step = 1'b0;
always @(posedge i_clk)
cmd_step <= (dbg_cmd_write)&&(dbg_idata[8]);
//
always @(posedge i_clk)
if (dbg_cmd_write)
cmd_addr <= dbg_idata[5:0];
end else if (cmd_step)
begin
cmd_halt <= 1'b1;
cmd_step <= 1'b0;
end else if (cpu_break)
cmd_halt <= 1'b1;
 
wire cpu_reset;
assign cpu_reset = (i_rst)||(cmd_reset)||(wdt_reset);
 
277,7 → 277,7
//
// Here's the stuff we'll be counting ....
//
wire cpu_mem_stall, cpu_pf_stall, cpu_alu_stall;
wire cpu_op_stall, cpu_pf_stall, cpu_i_count;
 
//
// The master counters will, in general, not be reset. They'll be used
291,29 → 291,29
sys_we, sys_data,
mtc_ack, mtc_stall, mtc_data, mtc_int);
 
// Master Memory-Stall counter
wire mmc_ack, mmc_stall, mmc_int;
wire [31:0] mmc_data;
zipcounter mmstall_ctr(i_clk,(~cmd_halt)&&(cpu_mem_stall), sys_cyc,
// Master Operand Stall counter
wire moc_ack, moc_stall, moc_int;
wire [31:0] moc_data;
zipcounter mmstall_ctr(i_clk,(cpu_op_stall), sys_cyc,
(sys_stb)&&(sys_addr == `MSTR_MSTL_CTR),
sys_we, sys_data,
mmc_ack, mmc_stall, mmc_data, mmc_int);
moc_ack, moc_stall, moc_data, moc_int);
 
// Master PreFetch-Stall counter
wire mpc_ack, mpc_stall, mpc_int;
wire [31:0] mpc_data;
zipcounter mpstall_ctr(i_clk,(~cmd_halt)&&(cpu_pf_stall), sys_cyc,
zipcounter mpstall_ctr(i_clk,(cpu_pf_stall), sys_cyc,
(sys_stb)&&(sys_addr == `MSTR_PSTL_CTR),
sys_we, sys_data,
mpc_ack, mpc_stall, mpc_data, mpc_int);
 
// Master ALU-Stall counter
wire mac_ack, mac_stall, mac_int;
wire [31:0] mac_data;
zipcounter mastall_ctr(i_clk,(~cmd_halt)&&(cpu_alu_stall), sys_cyc,
// Master Instruction counter
wire mic_ack, mic_stall, mic_int;
wire [31:0] mic_data;
zipcounter mins_ctr(i_clk,(cpu_i_count), sys_cyc,
(sys_stb)&&(sys_addr == `MSTR_ASTL_CTR),
sys_we, sys_data,
mac_ack, mac_stall, mac_data, mac_int);
mic_ack, mic_stall, mic_data, mic_int);
 
//
// The user counters are different from those of the master. They will
327,45 → 327,45
sys_we, sys_data,
utc_ack, utc_stall, utc_data, utc_int);
 
// User Memory-Stall counter
wire umc_ack, umc_stall, umc_int;
wire [31:0] umc_data;
zipcounter umstall_ctr(i_clk,(~cmd_halt)&&(cpu_mem_stall), sys_cyc,
// User Op-Stall counter
wire uoc_ack, uoc_stall, uoc_int;
wire [31:0] uoc_data;
zipcounter umstall_ctr(i_clk,(cpu_op_stall), sys_cyc,
(sys_stb)&&(sys_addr == `USER_MSTL_CTR),
sys_we, sys_data,
umc_ack, umc_stall, umc_data, umc_int);
uoc_ack, uoc_stall, uoc_data, uoc_int);
 
// User PreFetch-Stall counter
wire upc_ack, upc_stall, upc_int;
wire [31:0] upc_data;
zipcounter upstall_ctr(i_clk,(~cmd_halt)&&(cpu_pf_stall), sys_cyc,
zipcounter upstall_ctr(i_clk,(cpu_pf_stall), sys_cyc,
(sys_stb)&&(sys_addr == `USER_PSTL_CTR),
sys_we, sys_data,
upc_ack, upc_stall, upc_data, upc_int);
 
// User ALU-Stall counter
wire uac_ack, uac_stall, uac_int;
wire [31:0] uac_data;
zipcounter uastall_ctr(i_clk,(~cmd_halt)&&(cpu_alu_stall), sys_cyc,
// User instruction counter
wire uic_ack, uic_stall, uic_int;
wire [31:0] uic_data;
zipcounter uins_ctr(i_clk,(cpu_i_count), sys_cyc,
(sys_stb)&&(sys_addr == `USER_ASTL_CTR),
sys_we, sys_data,
uac_ack, uac_stall, uac_data, uac_int);
uic_ack, uic_stall, uic_data, uic_int);
 
// A little bit of pre-cleanup (actr = accounting counters)
wire actr_ack, actr_stall;
wire [31:0] actr_data;
assign actr_ack = ((mtc_ack | mmc_ack | mpc_ack | mac_ack)
|(utc_ack | umc_ack | upc_ack | uac_ack));
assign actr_stall = ((mtc_stall | mmc_stall | mpc_stall | mac_stall)
|(utc_stall | umc_stall | upc_stall|uac_stall));
assign actr_ack = ((mtc_ack | moc_ack | mpc_ack | mic_ack)
|(utc_ack | uoc_ack | upc_ack | uic_ack));
assign actr_stall = ((mtc_stall | moc_stall | mpc_stall | mic_stall)
|(utc_stall | uoc_stall | upc_stall|uic_stall));
assign actr_data = ((mtc_ack) ? mtc_data
: ((mmc_ack) ? mmc_data
: ((moc_ack) ? moc_data
: ((mpc_ack) ? mpc_data
: ((mac_ack) ? mac_data
: ((mic_ack) ? mic_data
: ((utc_ack) ? utc_data
: ((umc_ack) ? umc_data
: ((uoc_ack) ? uoc_data
: ((upc_ack) ? upc_data
: uac_data)))))));
: uic_data)))))));
 
 
377,8 → 377,8
wire [7:0] ctri_vector;
wire [31:0] ctri_data;
assign ctri_sel = (sys_cyc)&&(sys_stb)&&(sys_addr == `CTRINT);
assign ctri_vector = { mtc_int, mmc_int, mpc_int, mac_int,
utc_int, umc_int, upc_int, uac_int };
assign ctri_vector = { mtc_int, moc_int, mpc_int, mic_int,
utc_int, uoc_int, upc_int, uic_int };
icontrol #(8) ctri(i_clk, cpu_reset, (ctri_sel)&&(sys_addr==`CTRINT),
sys_data, ctri_data, ctri_vector, ctri_int);
always @(posedge i_clk)
456,7 → 456,7
cpu_break,
cpu_cyc, cpu_stb, cpu_we, cpu_addr, cpu_data,
cpu_ack, cpu_stall, wb_data,
cpu_mem_stall, cpu_pf_stall, cpu_alu_stall);
cpu_op_stall, cpu_pf_stall, cpu_i_count);
 
// Now, arbitrate the bus ... first for the local peripherals
assign sys_cyc = (cpu_cyc)||((cpu_halt)&&(~cpu_dbg_stall)&&(dbg_cyc));
/peripherals/zipjiffies.v
101,9 → 101,19
wire signed [(BW-1):0] till_when, till_wb;
assign till_when = int_when-r_counter;
assign till_wb = new_when-r_counter;
 
initial new_set = 1'b0;
always @(posedge i_clk)
// Delay things by a clock to simplify our logic
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
begin
new_set <= 1'b1;
new_when<= i_wb_data;
end else
new_set <= 1'b0;
 
initial o_int = 1'b0;
initial int_set = 1'b0;
initial new_set = 1'b0;
always @(posedge i_clk)
begin
o_int <= 1'b0;
113,19 → 123,11
int_set <= 1'b0;// Clear the interrupt
end
 
new_set <= 1'b0;
if ((new_set)&&(till_wb > 0)&&((till_wb<till_when)||(~int_set)))
begin
int_when <= new_when;
int_set <= ((int_set)||(till_wb>0));
end
// Delay things by a clock to simplify our logic
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
begin
new_set <= 1'b1;
new_when<= i_wb_data;
end
end
 
//
134,7 → 136,7
//
always @(posedge i_clk)
o_wb_ack <= (i_wb_cyc)&&(i_wb_stb);
 
assign o_wb_data = r_counter;
assign o_wb_stall = 1'b0;
 
endmodule
/peripherals/ziptimer.v
4,7 → 4,7
//
// Project: Zip CPU -- a small, lightweight, RISC CPU soft core
//
// Purpose:
// Purpose: A lighter weight implementation of the Zip Timer.
//
// Interface:
// Two options:
22,18 → 22,13
//
//
// Control bits:
// Start_n/Stop. Writing a '0' starts the timer, '1' stops it.
// Thus, ignoring this bit sets it to start.
// (Start_n/Stop. This bit has been dropped. Writing to this
// timer any value but zero starts it. Writing a zero
// clears and stops it.)
// AutoReload. If set, then on reset the timer automatically
// loads the last set value and starts over. This is
// useful for distinguishing between a one-time interrupt
// timer, and a repetitive interval timer.
// (COUNT: If set, the timer only ticks whenever an external
// line goes high. What this external line is ... is
// not specified here. This, however, breaks my
// interface ideal of having our peripheral set not depend
// upon anything. Hence, this is an advanced option
// enabled at compile time only.)
// (INTEN. Interrupt enable--reaching zero always creates an
// interrupt, so this control bit isn't needed. The
// interrupt controller can be used to mask the interrupt.)
72,7 → 67,7
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_data,
o_wb_ack, o_wb_stall, o_wb_data,
o_int);
parameter BW = 32, VW = (BW-2);
parameter BW = 32, VW = (BW-1);
input i_clk, i_rst, i_ce;
// Wishbone inputs
input i_wb_cyc, i_wb_stb, i_wb_we;
86,34 → 81,41
 
reg r_auto_reload, r_running;
reg [(VW-1):0] r_reload_value;
 
wire wb_write;
assign wb_write = ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we));
 
initial r_running = 1'b0;
initial r_auto_reload = 1'b0;
always @(posedge i_clk)
if (i_rst)
begin
r_running <= 1'b0;
r_auto_reload <= 1'b0;
end else if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
begin
r_running <= (~i_wb_data[(BW-1)])&&(|i_wb_data[(BW-2):0]);
r_auto_reload <= (i_wb_data[(BW-2)]);
else if (wb_write)
r_running <= (|i_wb_data[(VW-1):0]);
else if ((o_int)&&(~r_auto_reload))
r_running <= 1'b0;
 
// If setting auto-reload mode, and the value to other
// than zero, set the auto-reload value
if ((i_wb_data[(BW-2)])&&(|i_wb_data[(BW-3):0]))
r_reload_value <= i_wb_data[(BW-3):0];
end
 
always @(posedge i_clk)
if (wb_write)
r_auto_reload <= (i_wb_data[(BW-1)]);
 
// If setting auto-reload mode, and the value to other
// than zero, set the auto-reload value
always @(posedge i_clk)
if ((wb_write)&&(i_wb_data[(BW-1)])&&(|i_wb_data[(VW-1):0]))
r_reload_value <= i_wb_data[(VW-1):0];
 
reg [(VW-1):0] r_value;
initial r_value = 0;
always @(posedge i_clk)
if ((r_running)&&(|r_value)&&(i_ce))
begin
if (wb_write)
r_value <= i_wb_data[(VW-1):0];
else if ((r_running)&&(i_ce)&&(~o_int))
r_value <= r_value - 1;
end else if ((r_running)&&(r_auto_reload))
else if ((r_running)&&(r_auto_reload)&&(o_int))
r_value <= r_reload_value;
else if ((~r_running)&&(i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
r_value <= i_wb_data[(VW-1):0];
 
// Set the interrupt on our last tick.
initial o_int = 1'b0;
128,6 → 130,6
o_wb_ack <= (i_wb_cyc)&&(i_wb_stb);
assign o_wb_stall = 1'b0;
 
assign o_wb_data = { ~r_running, r_auto_reload, r_value };
assign o_wb_data = { r_auto_reload, r_value };
 
endmodule

powered by: WebSVN 2.1.0

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