diff --git a/system/Makefile b/system/Makefile index 8603941..82ad640 100644 --- a/system/Makefile +++ b/system/Makefile @@ -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... 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} - ${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 ${QUIET_NEXTPNR} diff --git a/system/fpga_config/OrangeCrab_r0.2.1/fpga_top.v b/system/fpga_config/OrangeCrab_r0.2.1/fpga_top.v index 145dc3a..1b4afdc 100644 --- a/system/fpga_config/OrangeCrab_r0.2.1/fpga_top.v +++ b/system/fpga_config/OrangeCrab_r0.2.1/fpga_top.v @@ -39,7 +39,7 @@ wire [19:0] address_bus; wire [15:0] data_bus_read,data_bus_write; wire rd,wr,BHE,IOMEM; -wire CPU_SPEED=counter[6]; +wire CPU_SPEED=clk48; system system( /* MISC */ CPU_SPEED,reset @@ -95,99 +95,21 @@ always @(posedge counter[15]) begin endcase 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 // chance to keep up with the relentless CPU -reg [5:0] disp_cache_start=0; -reg [5:0] disp_cache_end=0; -reg [7:0] disp_write_cache [63:0]; +reg [6:0] disp_cache_start=0; +reg [6:0] disp_cache_end=0; +reg [7:0] disp_write_cache [127:0]; reg ascii_state=0; always @(posedge CPU_SPEED)begin if(wr==0)begin if(IOMEM==1'b1 && address_bus[7:0]==8'hA5 )begin 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 if(data_bus_write[0:0]==1) rgb_led_color=3'b000; @@ -197,7 +119,7 @@ always @(posedge CPU_SPEED)begin end else if(ascii_state==1'b0)begin if(ascii_data_ready&disp_cache_start!=disp_cache_end)begin 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_state<=1'b1; end diff --git a/system/memory.v b/system/memory.v index e351325..cabbbef 100644 --- a/system/memory.v +++ b/system/memory.v @@ -19,7 +19,7 @@ /* This warning is because we don't use the full address bus. */ /* 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 */ 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 -always @(negedge wr) begin - if( cs == 0 ) begin +always @(posedge clock) begin + if( cs == 0 && wr == 0) begin if(BHE==0) memory[address[16:1]][7:0]<=cpu_write_data[15:8]; if(address[0]==0) diff --git a/system/peripherals/ascii_to_HD44780_driver.v b/system/peripherals/ascii_to_HD44780_driver.v index 95189c8..14ef0c5 100644 --- a/system/peripherals/ascii_to_HD44780_driver.v +++ b/system/peripherals/ascii_to_HD44780_driver.v @@ -121,62 +121,6 @@ always @(posedge clock) begin in_data_ready<=1; 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 if(next_line)begin case(line) diff --git a/system/processor.v b/system/processor.v index 4eb93aa..c187b3f 100644 --- a/system/processor.v +++ b/system/processor.v @@ -194,7 +194,8 @@ register_file register_file( /* READ 1 */ .read_port1_addr(reg_read_port1_addr), /* */ .read_port1_data(reg_read_port1_data), /* 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) ); /*############################################################################### */ diff --git a/system/registers.v b/system/registers.v index 33b6956..b6cf2dd 100644 --- a/system/registers.v +++ b/system/registers.v @@ -21,7 +21,8 @@ /* Register address format: * [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] read_port1_addr; input [3:0] read_port2_addr; @@ -48,47 +49,48 @@ assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr wire write_Wbit; assign write_Wbit=write_port1_addr[3:3]; -always @(negedge write_port1_we) begin - if(write_Wbit==1)begin - /* Word : AX,CX,DX,BX,SP,BP,SI,DI */ - registers[write_port1_addr[2:0]] <= write_port1_data; - end else begin - /* Byte : AL,CL,DL,BL,AX,CX,DX,BX */ - if(write_port1_addr[2:2]==1)begin - /* Byte */ - registers[ {1'b0,write_port1_addr[1:0]} ][15:8] <= write_port1_data[7:0]; +always @(posedge clock) begin + if(write_port1_we==0)begin + if(write_Wbit==1)begin + /* Word : AX,CX,DX,BX,SP,BP,SI,DI */ + registers[write_port1_addr[2:0]] <= write_port1_data; end else begin - /* Byte */ - registers[ {1'b0,write_port1_addr[1:0]} ][7:0] <= write_port1_data[7:0]; + /* Byte : AL,CL,DL,BL,AX,CX,DX,BX */ + if(write_port1_addr[2:2]==1)begin + /* Byte */ + registers[ {1'b0,write_port1_addr[1:0]} ][15:8] <= write_port1_data[7:0]; + end else begin + /* Byte */ + registers[ {1'b0,write_port1_addr[1:0]} ][7:0] <= write_port1_data[7:0]; + end end + `ifdef DEBUG_REG_WRITES + // Icarus Verilog really doesn't like non-blocking assignments + // here + /* verilator lint_off BLKSEQ */ + if(write_port1_addr[3:2]==2'b11)begin + case(write_port1_addr[1:0]) + 2'b00: debug_name="sp"; + 2'b01: debug_name="bp"; + 2'b10: debug_name="si"; + 2'b11: debug_name="di"; + endcase + end else begin + case(write_port1_addr[1:0]) + 2'b00: debug_name="ax"; + 2'b01: debug_name="cx"; + 2'b10: debug_name="dx"; + 2'b11: debug_name="bx"; + endcase + end + /* verilator lint_on BLKSEQ */ + if (write_Wbit) + debug_address<=write_port1_addr[2:0]; + else + debug_address<={1'b0,write_port1_addr[1:0]}; + + `endif end - `ifdef DEBUG_REG_WRITES - // Icarus Verilog really doesn't like non-blocking assignments - // here - /* verilator lint_off BLKSEQ */ - if(write_port1_addr[3:2]==2'b11)begin - case(write_port1_addr[1:0]) - 2'b00: debug_name="sp"; - 2'b01: debug_name="bp"; - 2'b10: debug_name="si"; - 2'b11: debug_name="di"; - endcase - end else begin - case(write_port1_addr[1:0]) - 2'b00: debug_name="ax"; - 2'b01: debug_name="cx"; - 2'b10: debug_name="dx"; - 2'b11: debug_name="bx"; - endcase - end - /* verilator lint_on BLKSEQ */ - if (write_Wbit) - debug_address<=write_port1_addr[2:0]; - else - debug_address<={1'b0,write_port1_addr[1:0]}; - - `endif - end `ifdef DEBUG_REG_WRITES diff --git a/system/system.v b/system/system.v index c8de6fd..73b55dc 100644 --- a/system/system.v +++ b/system/system.v @@ -49,7 +49,7 @@ processor p( `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 string stats_name,version,commit;