Project: The cpu finally works perfectly now even at full speed as far as i can tell! I made the ram and register writes synchronous which fixed the weird issues I had, then I added -abc9 to yosys so that nextpnr can actually route the cpu at full speed and increased the display fifo since the cpu is so fast now!!
This commit is contained in:
parent
29bc2e6d96
commit
aedefddb5d
@ -77,7 +77,7 @@ simplified_ucode.txt:ucode.txt
|
|||||||
#TODO: we are relying on yosys to trim the input program txt file and hope its enough for the whole program...
|
#TODO: we are relying on yosys to trim the input program txt file and hope its enough for the whole program...
|
||||||
synth_ecp5.json: ${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ${INCLUDES} ../boot_code/brainfuck_compiled.txt simplified_ucode.txt
|
synth_ecp5.json: ${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ${INCLUDES} ../boot_code/brainfuck_compiled.txt simplified_ucode.txt
|
||||||
${QUIET_YOSYS}
|
${QUIET_YOSYS}
|
||||||
${Q} yosys -q -D BUILTIN_RAM=2048 -D NOT_FULL -p 'read -sv '"${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ; synth_ecp5 -json $@ -top fpga_top"
|
${Q} yosys -q -D BUILTIN_RAM=2048 -D NOT_FULL -p 'read -sv '"${SOURCES} ${TOP_LEVEL_SOURCE} fpga_config/${FPGA_BOARD}/fpga_top.v ${EXTRA_SYNTHESIS_SOURCES} ; synth_ecp5 -json $@ -abc9 -top fpga_top"
|
||||||
|
|
||||||
synth_ecp5_out.config:synth_ecp5.json
|
synth_ecp5_out.config:synth_ecp5.json
|
||||||
${QUIET_NEXTPNR}
|
${QUIET_NEXTPNR}
|
||||||
|
@ -39,7 +39,7 @@ wire [19:0] address_bus;
|
|||||||
wire [15:0] data_bus_read,data_bus_write;
|
wire [15:0] data_bus_read,data_bus_write;
|
||||||
wire rd,wr,BHE,IOMEM;
|
wire rd,wr,BHE,IOMEM;
|
||||||
|
|
||||||
wire CPU_SPEED=counter[6];
|
wire CPU_SPEED=clk48;
|
||||||
|
|
||||||
system system(
|
system system(
|
||||||
/* MISC */ CPU_SPEED,reset
|
/* MISC */ CPU_SPEED,reset
|
||||||
@ -95,99 +95,21 @@ always @(posedge counter[15]) begin
|
|||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
/* TODO This seems to be a bug with YOSYS. If I don't initialise the memory
|
|
||||||
* it doesn't work (even though it does in sim), and for example if i
|
|
||||||
* initialise 1 twice to the same value it breaks again.
|
|
||||||
*
|
|
||||||
* This seems to affect brainfuck_compiled.asm and specifically when the
|
|
||||||
* compiled code starts running ( or the compiler i guess )
|
|
||||||
*/
|
|
||||||
initial begin
|
|
||||||
disp_write_cache[ 0]=8'h46;
|
|
||||||
disp_write_cache[ 1]=8'h46;
|
|
||||||
disp_write_cache[ 2]=8'h46;
|
|
||||||
disp_write_cache[ 3]=8'h46;
|
|
||||||
disp_write_cache[ 4]=8'h46;
|
|
||||||
disp_write_cache[ 5]=8'h46;
|
|
||||||
disp_write_cache[ 6]=8'h46;
|
|
||||||
disp_write_cache[ 7]=8'h46;
|
|
||||||
disp_write_cache[ 8]=8'h46;
|
|
||||||
disp_write_cache[ 9]=8'h46;
|
|
||||||
disp_write_cache[10]=8'h46;
|
|
||||||
disp_write_cache[11]=8'h46;
|
|
||||||
disp_write_cache[12]=8'h46;
|
|
||||||
disp_write_cache[13]=8'h46;
|
|
||||||
disp_write_cache[14]=8'h46;
|
|
||||||
disp_write_cache[15]=8'h46;
|
|
||||||
disp_write_cache[16]=8'h46;
|
|
||||||
disp_write_cache[17]=8'h46;
|
|
||||||
disp_write_cache[18]=8'h46;
|
|
||||||
disp_write_cache[19]=8'h46;
|
|
||||||
disp_write_cache[20]=8'h46;
|
|
||||||
disp_write_cache[21]=8'h46;
|
|
||||||
disp_write_cache[22]=8'h46;
|
|
||||||
disp_write_cache[23]=8'h46;
|
|
||||||
disp_write_cache[24]=8'h46;
|
|
||||||
disp_write_cache[25]=8'h46;
|
|
||||||
disp_write_cache[26]=8'h46;
|
|
||||||
disp_write_cache[27]=8'h46;
|
|
||||||
disp_write_cache[28]=8'h46;
|
|
||||||
disp_write_cache[29]=8'h46;
|
|
||||||
disp_write_cache[30]=8'h46;
|
|
||||||
disp_write_cache[31]=8'h46;
|
|
||||||
disp_write_cache[32]=8'h46;
|
|
||||||
disp_write_cache[33]=8'h46;
|
|
||||||
disp_write_cache[34]=8'h46;
|
|
||||||
disp_write_cache[35]=8'h46;
|
|
||||||
disp_write_cache[36]=8'h46;
|
|
||||||
disp_write_cache[37]=8'h46;
|
|
||||||
disp_write_cache[38]=8'h46;
|
|
||||||
disp_write_cache[39]=8'h46;
|
|
||||||
disp_write_cache[40]=8'h46;
|
|
||||||
disp_write_cache[41]=8'h46;
|
|
||||||
disp_write_cache[42]=8'h46;
|
|
||||||
disp_write_cache[43]=8'h46;
|
|
||||||
disp_write_cache[44]=8'h46;
|
|
||||||
disp_write_cache[45]=8'h46;
|
|
||||||
disp_write_cache[46]=8'h46;
|
|
||||||
disp_write_cache[47]=8'h46;
|
|
||||||
disp_write_cache[48]=8'h46;
|
|
||||||
disp_write_cache[49]=8'h46;
|
|
||||||
disp_write_cache[50]=8'h46;
|
|
||||||
disp_write_cache[51]=8'h46;
|
|
||||||
disp_write_cache[52]=8'h46;
|
|
||||||
disp_write_cache[53]=8'h46;
|
|
||||||
disp_write_cache[54]=8'h46;
|
|
||||||
disp_write_cache[55]=8'h46;
|
|
||||||
disp_write_cache[56]=8'h46;
|
|
||||||
disp_write_cache[57]=8'h46;
|
|
||||||
disp_write_cache[58]=8'h46;
|
|
||||||
disp_write_cache[59]=8'h46;
|
|
||||||
disp_write_cache[60]=8'h46;
|
|
||||||
disp_write_cache[61]=8'h46;
|
|
||||||
disp_write_cache[62]=8'h46;
|
|
||||||
disp_write_cache[63]=8'h46;
|
|
||||||
end
|
|
||||||
|
|
||||||
//TODO similarly as above, if I remove this the same thing breaks
|
|
||||||
always @(negedge wr) begin
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
// Cache to allow the slow display to have a
|
// Cache to allow the slow display to have a
|
||||||
// chance to keep up with the relentless CPU
|
// chance to keep up with the relentless CPU
|
||||||
|
|
||||||
reg [5:0] disp_cache_start=0;
|
reg [6:0] disp_cache_start=0;
|
||||||
reg [5:0] disp_cache_end=0;
|
reg [6:0] disp_cache_end=0;
|
||||||
reg [7:0] disp_write_cache [63:0];
|
reg [7:0] disp_write_cache [127:0];
|
||||||
reg ascii_state=0;
|
reg ascii_state=0;
|
||||||
always @(posedge CPU_SPEED)begin
|
always @(posedge CPU_SPEED)begin
|
||||||
|
|
||||||
if(wr==0)begin
|
if(wr==0)begin
|
||||||
if(IOMEM==1'b1 && address_bus[7:0]==8'hA5 )begin
|
if(IOMEM==1'b1 && address_bus[7:0]==8'hA5 )begin
|
||||||
disp_write_cache[disp_cache_end]<=data_bus_write[15:8];
|
disp_write_cache[disp_cache_end]<=data_bus_write[15:8];
|
||||||
disp_cache_end<=disp_cache_end+6'd1;
|
disp_cache_end<=disp_cache_end+7'd1;
|
||||||
end else if(IOMEM==1'b1 && address_bus[7:0]==8'hB0 )begin
|
end else if(IOMEM==1'b1 && address_bus[7:0]==8'hB0 )begin
|
||||||
if(data_bus_write[0:0]==1)
|
if(data_bus_write[0:0]==1)
|
||||||
rgb_led_color=3'b000;
|
rgb_led_color=3'b000;
|
||||||
@ -197,7 +119,7 @@ always @(posedge CPU_SPEED)begin
|
|||||||
end else if(ascii_state==1'b0)begin
|
end else if(ascii_state==1'b0)begin
|
||||||
if(ascii_data_ready&disp_cache_start!=disp_cache_end)begin
|
if(ascii_data_ready&disp_cache_start!=disp_cache_end)begin
|
||||||
ascii_data<=disp_write_cache[disp_cache_start];
|
ascii_data<=disp_write_cache[disp_cache_start];
|
||||||
disp_cache_start<=disp_cache_start+6'd1;
|
disp_cache_start<=disp_cache_start+7'd1;
|
||||||
ascii_data_write_req<=1;
|
ascii_data_write_req<=1;
|
||||||
ascii_state<=1'b1;
|
ascii_state<=1'b1;
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
/* This warning is because we don't use the full address bus. */
|
/* This warning is because we don't use the full address bus. */
|
||||||
/* verilator lint_off UNUSEDSIGNAL */
|
/* verilator lint_off UNUSEDSIGNAL */
|
||||||
module doublemem(input [19:0] address,output [15:0] cpu_read_data ,input [15:0] cpu_write_data,input rd,input wr,input BHE,input cs);
|
module doublemem(input [19:0] address,output [15:0] cpu_read_data ,input [15:0] cpu_write_data,input rd,input wr,input BHE,input cs,input clock);
|
||||||
/* verilator lint_on UNUSEDSIGNAL */
|
/* verilator lint_on UNUSEDSIGNAL */
|
||||||
|
|
||||||
reg [15:0] memory [0:`BUILTIN_RAM];
|
reg [15:0] memory [0:`BUILTIN_RAM];
|
||||||
@ -58,8 +58,8 @@ assign cpu_read_data[15:8] = !BHE & !rd & !cs ? (address[15:4]==12'b1111
|
|||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
always @(negedge wr) begin
|
always @(posedge clock) begin
|
||||||
if( cs == 0 ) begin
|
if( cs == 0 && wr == 0) begin
|
||||||
if(BHE==0)
|
if(BHE==0)
|
||||||
memory[address[16:1]][7:0]<=cpu_write_data[15:8];
|
memory[address[16:1]][7:0]<=cpu_write_data[15:8];
|
||||||
if(address[0]==0)
|
if(address[0]==0)
|
||||||
|
@ -121,62 +121,6 @@ always @(posedge clock) begin
|
|||||||
in_data_ready<=1;
|
in_data_ready<=1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
/* TODO: These are unreachable states but from
|
|
||||||
* what i assume to be a bug in yosys. They need
|
|
||||||
* to be here for brainfuck_compiled.asm to work.
|
|
||||||
* Specifically for the compiled program to not output
|
|
||||||
* random characters.
|
|
||||||
*/
|
|
||||||
8'd14:begin
|
|
||||||
data<=4'hf;
|
|
||||||
next_line<=1;
|
|
||||||
if(!done_writing)begin
|
|
||||||
driver_state<=8'd1;
|
|
||||||
write_req<=1'b0;
|
|
||||||
end else
|
|
||||||
write_req<=1'b1;
|
|
||||||
end
|
|
||||||
8'd13:begin
|
|
||||||
data<=4'hf;
|
|
||||||
if(!done_writing)begin
|
|
||||||
driver_state<=8'd1;
|
|
||||||
write_req<=1'b0;
|
|
||||||
end else
|
|
||||||
write_req<=1'b1;
|
|
||||||
end
|
|
||||||
8'd1:begin
|
|
||||||
if(done_writing==1)
|
|
||||||
driver_state<=8'd2;
|
|
||||||
end
|
|
||||||
8'd2:begin
|
|
||||||
data<=4'hE;
|
|
||||||
if(!done_writing)begin
|
|
||||||
driver_state<=8'd3;
|
|
||||||
write_req<=1'b0;
|
|
||||||
end else
|
|
||||||
write_req<=1'b1;
|
|
||||||
end
|
|
||||||
8'd3:begin
|
|
||||||
if(done_writing==1)
|
|
||||||
driver_state<=8'd4;
|
|
||||||
end
|
|
||||||
8'd4:begin
|
|
||||||
data<=4'h0;
|
|
||||||
cmd_data<=1'b0;
|
|
||||||
if(!done_writing)begin
|
|
||||||
driver_state<=8'd5;
|
|
||||||
write_req<=1'b0;
|
|
||||||
end else
|
|
||||||
write_req<=1'b1;
|
|
||||||
end
|
|
||||||
8'd5:begin
|
|
||||||
if(done_writing==1)
|
|
||||||
driver_state<=8'd6;
|
|
||||||
end
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
|
|
||||||
8'd6:begin
|
8'd6:begin
|
||||||
if(next_line)begin
|
if(next_line)begin
|
||||||
case(line)
|
case(line)
|
||||||
|
@ -194,7 +194,8 @@ register_file register_file(
|
|||||||
/* READ 1 */ .read_port1_addr(reg_read_port1_addr),
|
/* READ 1 */ .read_port1_addr(reg_read_port1_addr),
|
||||||
/* */ .read_port1_data(reg_read_port1_data),
|
/* */ .read_port1_data(reg_read_port1_data),
|
||||||
/* READ 2 */ .read_port2_addr(DE_reg_read_port2_addr),
|
/* READ 2 */ .read_port2_addr(DE_reg_read_port2_addr),
|
||||||
/* */ .read_port2_data(reg_read_port2_data)
|
/* */ .read_port2_data(reg_read_port2_data),
|
||||||
|
/* GENERAL */ .clock(clock)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*############################################################################### */
|
/*############################################################################### */
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
/* Register address format:
|
/* Register address format:
|
||||||
* [W-bit] [ 3-bit address] */
|
* [W-bit] [ 3-bit address] */
|
||||||
module register_file (write_port1_addr,write_port1_data,write_port1_we,read_port1_addr,read_port1_data,read_port2_addr,read_port2_data);
|
module register_file (write_port1_addr,write_port1_data,write_port1_we,read_port1_addr,read_port1_data,read_port2_addr,read_port2_data,clock);
|
||||||
|
input clock;
|
||||||
input [3:0] write_port1_addr;
|
input [3:0] write_port1_addr;
|
||||||
input [3:0] read_port1_addr;
|
input [3:0] read_port1_addr;
|
||||||
input [3:0] read_port2_addr;
|
input [3:0] read_port2_addr;
|
||||||
@ -48,7 +49,8 @@ assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr
|
|||||||
wire write_Wbit;
|
wire write_Wbit;
|
||||||
assign write_Wbit=write_port1_addr[3:3];
|
assign write_Wbit=write_port1_addr[3:3];
|
||||||
|
|
||||||
always @(negedge write_port1_we) begin
|
always @(posedge clock) begin
|
||||||
|
if(write_port1_we==0)begin
|
||||||
if(write_Wbit==1)begin
|
if(write_Wbit==1)begin
|
||||||
/* Word : AX,CX,DX,BX,SP,BP,SI,DI */
|
/* Word : AX,CX,DX,BX,SP,BP,SI,DI */
|
||||||
registers[write_port1_addr[2:0]] <= write_port1_data;
|
registers[write_port1_addr[2:0]] <= write_port1_data;
|
||||||
@ -88,7 +90,7 @@ always @(negedge write_port1_we) begin
|
|||||||
debug_address<={1'b0,write_port1_addr[1:0]};
|
debug_address<={1'b0,write_port1_addr[1:0]};
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
`ifdef DEBUG_REG_WRITES
|
`ifdef DEBUG_REG_WRITES
|
||||||
|
@ -49,7 +49,7 @@ processor p(
|
|||||||
`endif
|
`endif
|
||||||
);
|
);
|
||||||
|
|
||||||
doublemem sysmem(address_bus,data_bus_read_,data_bus_write_,rd,wr,BHE,IOMEM);
|
doublemem sysmem(address_bus,data_bus_read_,data_bus_write_,rd,wr,BHE,IOMEM,clock);
|
||||||
|
|
||||||
`ifdef OUTPUT_JSON_STATISTICS
|
`ifdef OUTPUT_JSON_STATISTICS
|
||||||
string stats_name,version,commit;
|
string stats_name,version,commit;
|
||||||
|
Loading…
Reference in New Issue
Block a user