Fixed clock cycle counter overflow, reset circuitry for icarus verilog and implemented statistics recording
This commit is contained in:
parent
88a47cc4a9
commit
98e73af5da
9
.gitignore
vendored
9
.gitignore
vendored
@ -5,12 +5,9 @@
|
||||
*.bf.asm
|
||||
*.swp
|
||||
*.memdump
|
||||
boot_code/brainfuck_interpreted.bin
|
||||
boot_code/brainfuck_interpreted.txt
|
||||
boot_code/brainfuck_mandelbrot.bin
|
||||
boot_code/brainfuck_mandelbrot.txt
|
||||
boot_code/brainfuck_compiled.bin
|
||||
boot_code/brainfuck_compiled.txt
|
||||
*.json
|
||||
boot_code/*.bin
|
||||
boot_code/*.txt
|
||||
system/boot_code.bin
|
||||
system/boot_code.txt
|
||||
system/obj_dir/
|
||||
|
@ -57,6 +57,10 @@ ifeq "${SIM}" "ICARUS"
|
||||
%.run: %.txt ${SYSTEM_VVP} ${MICROCODE}
|
||||
${QUIET_VVP}
|
||||
${Q}vvp -i "${SYSTEM_VVP}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
||||
|
||||
%.json: %.txt ${SYSTEM_VVP} ${MICROCODE}
|
||||
${QUIET_VVP}
|
||||
${Q}vvp -i "${SYSTEM_VVP}" +STATS="$@" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
||||
else ifeq "${SIM}" "VERILATOR"
|
||||
%.fst %.memdump: %.txt ${VERILATOR_BIN} ${MICROCODE}
|
||||
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
|
||||
@ -64,6 +68,10 @@ else ifeq "${SIM}" "VERILATOR"
|
||||
${Q}grep -v '^//' "$(subst .txt,.memdumptxt,$<)" | xxd -ps -c 2 -r > "$(subst .txt,.memdump,$<)"
|
||||
${Q}rm "$(subst .txt,.memdumptxt,$<)"
|
||||
|
||||
%.json: %.txt ${VERILATOR_BIN} ${MICROCODE}
|
||||
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
|
||||
${Q} ${NUMACTL} "${VERILATOR_BIN}" +STATS=$@ +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
||||
|
||||
%.run: %.txt ${VERILATOR_BIN} ${MICROCODE}
|
||||
$(call QUIET_VERILATOR_RUN,$(word 2,$^),$<)
|
||||
${Q} ${NUMACTL} "${VERILATOR_BIN}" +BOOT_CODE="$<" +MICROCODE="${MICROCODE}"
|
||||
|
@ -21,3 +21,12 @@
|
||||
//`define DEBUG_REG_WRITES
|
||||
//`define DEBUG_PC_ADDRESS
|
||||
//`define DEBUG_MEMORY_WRITES
|
||||
|
||||
`define CALCULATE_IPC
|
||||
`define OUTPUT_JSON_STATISTICS
|
||||
|
||||
/********** Internal **********/
|
||||
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
`define CALCULATE_IPC
|
||||
`endif
|
||||
|
@ -29,7 +29,17 @@
|
||||
//read: active low
|
||||
//reset: active low
|
||||
|
||||
module processor ( input clock, input reset, output reg [19:0] external_address_bus, inout [15:0] external_data_bus,output reg read, output reg write,output reg BHE,output reg IOMEM, output reg HALT,output reg ERROR);
|
||||
module processor (
|
||||
/* MISC */ input clock, input reset, output reg HALT,output reg ERROR
|
||||
/* MEMORY / IO */ ,output reg [19:0] external_address_bus, inout [15:0] external_data_bus,output reg read, output reg write,output reg BHE,output reg IOMEM
|
||||
`ifdef CALCULATE_IPC
|
||||
/* STATISTICS */ ,output reg new_instruction
|
||||
`endif
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
/* */ , output reg jump_debug
|
||||
`endif
|
||||
);
|
||||
|
||||
|
||||
/*if we don't read, output the register to have the bus stable by the write falling edge*/
|
||||
reg [15:0] data_bus_output_register;
|
||||
@ -198,6 +208,12 @@ always @(posedge clock) begin
|
||||
reg_write_we <= 1;
|
||||
instruction_size_init <= 1;
|
||||
state <= `PROC_IF_STATE_ENTRY;
|
||||
`ifdef CALCULATE_IPC
|
||||
new_instruction <= 0;
|
||||
`endif
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
jump_debug <= 0;
|
||||
`endif
|
||||
end
|
||||
`PROC_HALT_STATE:begin
|
||||
end
|
||||
@ -210,6 +226,9 @@ always @(posedge clock) begin
|
||||
reg_write_we <= 1;
|
||||
state <= `PROC_IF_WRITE_CIR;
|
||||
reg_write_in_sel <= 2'b00;
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
jump_debug <= 0;
|
||||
`endif
|
||||
end
|
||||
`PROC_IF_WRITE_CIR:begin
|
||||
`ifdef DEBUG_PC_ADDRESS
|
||||
@ -224,6 +243,9 @@ always @(posedge clock) begin
|
||||
$display("Fetched instruction at %0x",ProgCount - 0);
|
||||
end
|
||||
`endif
|
||||
`ifdef CALCULATE_IPC
|
||||
new_instruction <= !new_instruction;
|
||||
`endif
|
||||
/*I built the entire decode stage with CIR
|
||||
* being big endian so just convert it here*/
|
||||
|
||||
@ -523,6 +545,9 @@ always @(posedge clock) begin
|
||||
state <= `PROC_NEXT_MICROCODE;
|
||||
end
|
||||
3'b101:begin /* Program Counter*/
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
jump_debug <= 1;
|
||||
`endif
|
||||
ProgCount <= ALU_1O[15:0];
|
||||
instruction_size_init <= 1;
|
||||
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
|
||||
@ -609,6 +634,9 @@ always @(posedge clock) begin
|
||||
state <= `PROC_NEXT_MICROCODE;
|
||||
end
|
||||
`PROC_NEXT_MICROCODE:begin
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
jump_debug <= 0;
|
||||
`endif
|
||||
read <= 0;
|
||||
write <= 1; // maybe we are coming from MEMIO_WRITE
|
||||
BHE <= 0;
|
||||
|
@ -18,31 +18,78 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
`timescale 1ns/1ps
|
||||
`include "config.v"
|
||||
|
||||
|
||||
module system ( input clock,input reset, output [19:0]address_bus, inout [15:0]data_bus,output BHE, output rd, output wr, output IOMEM, output HALT, output ERROR);
|
||||
processor p(clock,reset,address_bus,data_bus,rd,wr,BHE,IOMEM,HALT,ERROR);
|
||||
|
||||
`ifdef CALCULATE_IPC
|
||||
wire new_instruction;
|
||||
`endif
|
||||
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
wire jump;
|
||||
`endif
|
||||
|
||||
processor p(
|
||||
/* MISC */ clock,reset,HALT,ERROR
|
||||
/* MEMORY / IO */ ,address_bus,data_bus,rd,wr,BHE,IOMEM
|
||||
`ifdef CALCULATE_IPC
|
||||
/* STATISTICS */ ,new_instruction
|
||||
`endif
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
/* */ , jump
|
||||
`endif
|
||||
);
|
||||
|
||||
doublemem sysmem(address_bus,data_bus,rd,wr,BHE,IOMEM);
|
||||
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
string stats_name;
|
||||
integer json_file_descriptor;
|
||||
`endif
|
||||
string waveform_name;
|
||||
initial begin
|
||||
if($value$plusargs("WAVEFORM=%s",waveform_name))begin
|
||||
$dumpfile(waveform_name);
|
||||
$dumpvars(0,p);
|
||||
end
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
if($value$plusargs("STATS=%s",stats_name))begin
|
||||
json_file_descriptor=$fopen(stats_name,"w");
|
||||
$fdisplay(json_file_descriptor,"{\n\"L1_size\":0,\n\"Cycles\":[");
|
||||
first_json_cycle = 1;
|
||||
end else
|
||||
json_file_descriptor=0;
|
||||
`endif
|
||||
end
|
||||
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
reg first_json_cycle;
|
||||
always @(negedge clock)begin
|
||||
if(HALT==0 && json_file_descriptor!=0)begin
|
||||
$fdisplay(json_file_descriptor,"%s{\"C\":%0d,\"JMP\":%0d}",first_json_cycle?"":",",cycles,jump);
|
||||
first_json_cycle <= 0;
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
always @(negedge wr) begin
|
||||
if(IOMEM==1'b1 && address_bus[7:0]==8'hA5 )
|
||||
$write("%s" ,data_bus[15:8]);
|
||||
end
|
||||
|
||||
`ifdef CALCULATE_IPC
|
||||
reg [128:0] instruction_count;
|
||||
always @(new_instruction) begin
|
||||
instruction_count<=instruction_count+1;
|
||||
end
|
||||
`endif
|
||||
|
||||
reg [1:0] finish;
|
||||
|
||||
string memdump_name;
|
||||
always @(posedge HALT) begin
|
||||
$display("Processor halted.\nCycles run for: %d",cycles-1);
|
||||
if($value$plusargs("MEMDUMP=%s",memdump_name))begin
|
||||
$writememh(memdump_name, sysmem.memory,0,32767);
|
||||
end
|
||||
@ -53,7 +100,17 @@ always @(posedge clock) begin
|
||||
/* Allow some clock cycles for the waveform*/
|
||||
case(finish)
|
||||
2'd0: begin end
|
||||
2'd1: finish <= 2;
|
||||
2'd1: begin
|
||||
finish <= 2;
|
||||
$display("\x1b[7mProcessor halted.\nCycles run for : %0d\x1b[m",cycles);
|
||||
`ifdef CALCULATE_IPC
|
||||
$display("\x1b[7mInstr. per cycle : %f\x1b[m", $itor(instruction_count) / $itor(cycles) );
|
||||
`endif
|
||||
`ifdef OUTPUT_JSON_STATISTICS
|
||||
if(json_file_descriptor!=0)
|
||||
$fdisplay(json_file_descriptor,"],\n\"Total Cycles\":%0d,\n\"Instructions run\":%0d\n}",cycles,instruction_count);
|
||||
`endif
|
||||
end
|
||||
2'd2: finish <= 3;
|
||||
2'd3: $finish;
|
||||
endcase
|
||||
@ -67,13 +124,17 @@ always @(posedge ERROR) begin
|
||||
finish<=2'd1;
|
||||
end
|
||||
|
||||
integer cycles=0;
|
||||
reg [128:0] cycles=0;
|
||||
|
||||
always @(posedge clock)begin
|
||||
always @(negedge clock)begin
|
||||
if(reset==1)
|
||||
cycles<=cycles+1;
|
||||
else
|
||||
else begin
|
||||
cycles<=0;
|
||||
`ifdef CALCULATE_IPC
|
||||
instruction_count <= 0;
|
||||
`endif
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -46,13 +46,28 @@ clock_gen #(.FREQ(1000)) u1(clk_enable, clock);
|
||||
string memdump_name;
|
||||
initial begin
|
||||
clk_enable = 1;
|
||||
do_reset = 0;
|
||||
reset<=1;
|
||||
end
|
||||
|
||||
reset = 1;
|
||||
#(`CPU_SPEED*2)
|
||||
reset = 0;
|
||||
#($random%1000)
|
||||
#(`CPU_SPEED)
|
||||
reset = 1;
|
||||
reg [1:0]do_reset;
|
||||
|
||||
always @(posedge clock) begin
|
||||
case(do_reset)
|
||||
2'd0:begin
|
||||
do_reset<=1;
|
||||
end
|
||||
2'd1:begin
|
||||
do_reset<=2;
|
||||
reset <= 0;
|
||||
end
|
||||
2'd2:begin
|
||||
do_reset<=3;
|
||||
reset <= 1;
|
||||
end
|
||||
2'd3:begin
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user