Peripherals/HD44780: Rewrote and cleaned up a lot of the driver code. Unfortunately what i think is a very weird bug in yosys is still affecting the codebase
This commit is contained in:
parent
0ca1da81b1
commit
09ccce5f30
@ -39,9 +39,10 @@ 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];
|
||||||
|
|
||||||
system system(
|
system system(
|
||||||
/* MISC */ counter[9],reset
|
/* MISC */ CPU_SPEED,reset
|
||||||
/* MEMORY / IO */ ,address_bus,data_bus_read,data_bus_write,BHE,rd,wr,IOMEM,HALT,ERROR
|
/* MEMORY / IO */ ,address_bus,data_bus_read,data_bus_write,BHE,rd,wr,IOMEM,HALT,ERROR
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -94,22 +95,85 @@ 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.
|
||||||
always @(negedge wr) begin
|
*
|
||||||
if(IOMEM==1'b1 && address_bus[7:0]==8'hA5 )begin
|
* This seems to affect brainfuck_compiled.asm and specifically when the
|
||||||
//disp_write_cache[disp_cache_end]<=data_bus_write[7:0];
|
* compiled code starts running ( or the compiler i guess )
|
||||||
disp_write_cache[disp_cache_end]<=data_bus_write[15:8];
|
*/
|
||||||
disp_cache_end<=disp_cache_end+6'd1;
|
initial begin
|
||||||
end else if(IOMEM==1'b1 && address_bus[7:0]==8'hB0 )begin
|
disp_write_cache[ 0]=8'h46;
|
||||||
if(data_bus_write[0:0]==1)
|
disp_write_cache[ 1]=8'h46;
|
||||||
rgb_led_color=3'b000;
|
disp_write_cache[ 2]=8'h46;
|
||||||
else
|
disp_write_cache[ 3]=8'h46;
|
||||||
rgb_led_color=3'b111;
|
disp_write_cache[ 4]=8'h46;
|
||||||
end
|
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
|
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
|
||||||
@ -118,9 +182,19 @@ reg [5:0] disp_cache_start=0;
|
|||||||
reg [5:0] disp_cache_end=0;
|
reg [5:0] disp_cache_end=0;
|
||||||
reg [7:0] disp_write_cache [63:0];
|
reg [7:0] disp_write_cache [63:0];
|
||||||
reg ascii_state=0;
|
reg ascii_state=0;
|
||||||
always @(posedge clk48)begin
|
always @(posedge CPU_SPEED)begin
|
||||||
case (ascii_state)
|
|
||||||
1'b0: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;
|
||||||
|
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;
|
||||||
|
else
|
||||||
|
rgb_led_color=3'b111;
|
||||||
|
end
|
||||||
|
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+6'd1;
|
||||||
@ -128,14 +202,13 @@ always @(posedge clk48)begin
|
|||||||
ascii_state<=1'b1;
|
ascii_state<=1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
1'b1:begin
|
|
||||||
|
if(ascii_state==1'b1)begin
|
||||||
if(!ascii_data_ready)begin
|
if(!ascii_data_ready)begin
|
||||||
ascii_data_write_req<=0;
|
ascii_data_write_req<=0;
|
||||||
ascii_state<=1'b0;
|
ascii_state<=1'b0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
default: begin end
|
|
||||||
endcase
|
|
||||||
end
|
end
|
||||||
|
|
||||||
wire I2C_SPEED=counter[7];
|
wire I2C_SPEED=counter[7];
|
||||||
@ -190,7 +263,7 @@ pcf8574_for_HD44780 PCF8574_driver(
|
|||||||
wire SCL,SDA,I2C_BUSY,I2C_SEND;
|
wire SCL,SDA,I2C_BUSY,I2C_SEND;
|
||||||
assign gpio_1=SCL;
|
assign gpio_1=SCL;
|
||||||
assign gpio_0=SDA;
|
assign gpio_0=SDA;
|
||||||
reg [7:0]i2c_data;
|
|
||||||
I2C_driver i2c_driver(
|
I2C_driver i2c_driver(
|
||||||
.clock(I2C_SPEED),
|
.clock(I2C_SPEED),
|
||||||
|
|
||||||
@ -200,7 +273,7 @@ I2C_driver i2c_driver(
|
|||||||
.address(7'h27),
|
.address(7'h27),
|
||||||
.I2C_BUSY(I2C_BUSY),
|
.I2C_BUSY(I2C_BUSY),
|
||||||
.I2C_SEND(I2C_SEND),
|
.I2C_SEND(I2C_SEND),
|
||||||
.i2c_data(i2c_data),
|
.i2c_data(i2c_data)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -44,8 +44,8 @@ initial begin
|
|||||||
init_cmd_data[ 5] = 4'h8;
|
init_cmd_data[ 5] = 4'h8;
|
||||||
init_cmd_data[ 6] = 4'h0; //0x07
|
init_cmd_data[ 6] = 4'h0; //0x07
|
||||||
init_cmd_data[ 7] = 4'h7;
|
init_cmd_data[ 7] = 4'h7;
|
||||||
init_cmd_data[ 8] = 4'h0; //0x0C
|
init_cmd_data[ 8] = 4'h0; //0x0F
|
||||||
init_cmd_data[ 9] = 4'hC;
|
init_cmd_data[ 9] = 4'hF;
|
||||||
init_cmd_data[10] = 4'h0; //0x01
|
init_cmd_data[10] = 4'h0; //0x01
|
||||||
init_cmd_data[11] = 4'h1;
|
init_cmd_data[11] = 4'h1;
|
||||||
init_cmd_data[12] = 4'h0; //0x06
|
init_cmd_data[12] = 4'h0; //0x06
|
||||||
@ -55,12 +55,9 @@ initial begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
reg [4:0] init_seq=0;
|
reg [4:0] init_seq=0;
|
||||||
reg [5:0] data_write_wait_counter = 0;
|
|
||||||
|
|
||||||
reg [3:0] init_cmd_data [15:0];
|
reg [3:0] init_cmd_data [15:0];
|
||||||
|
|
||||||
reg byte_n=0;
|
|
||||||
|
|
||||||
reg [7:0]print_data;
|
reg [7:0]print_data;
|
||||||
|
|
||||||
reg [1:0]line=0;
|
reg [1:0]line=0;
|
||||||
@ -70,67 +67,84 @@ reg [7:0] driver_state =0;
|
|||||||
|
|
||||||
reg next_line;
|
reg next_line;
|
||||||
|
|
||||||
always @(posedge clock,negedge rst_n) begin
|
always @(posedge clock) begin
|
||||||
if(rst_n==0)begin
|
if(rst_n==0)begin
|
||||||
in_data_ready<=0;
|
in_data_ready<=0;
|
||||||
write_req<=1'b0;
|
write_req<=1'b0;
|
||||||
init_seq<=5'd0;
|
init_seq<=5'd0;
|
||||||
data_write_wait_counter<=6'd0;
|
|
||||||
byte_n<=1'b0;
|
|
||||||
cmd_data<=1'b0;
|
cmd_data<=1'b0;
|
||||||
line<=0;
|
line<=0;
|
||||||
col<=0;
|
col<=0;
|
||||||
driver_state<=0;
|
driver_state<=0;
|
||||||
end else begin
|
|
||||||
if (data_write_wait_counter!=6'd0 && done_writing) begin
|
|
||||||
data_write_wait_counter<=data_write_wait_counter-6'd1;
|
|
||||||
write_req<=1'b0;
|
|
||||||
in_data_ready<=0;
|
|
||||||
end else begin
|
end else begin
|
||||||
case(driver_state)
|
case(driver_state)
|
||||||
8'd0:begin
|
8'd0:begin
|
||||||
if(done_writing)begin
|
if(init_seq!=5'd16)begin
|
||||||
if(init_seq!=5'd16&&data_write_wait_counter==6'd0)begin
|
|
||||||
/** Initialise display **/
|
/** Initialise display **/
|
||||||
data<=init_cmd_data[init_seq[3:0]];
|
data<=init_cmd_data[init_seq[3:0]];
|
||||||
init_seq<=init_seq+5'd1;
|
cmd_data<=1'b0;
|
||||||
write_req<=1'b1;
|
|
||||||
data_write_wait_counter<=6'd50;
|
|
||||||
in_data_ready<=0;
|
in_data_ready<=0;
|
||||||
|
if(!done_writing)begin
|
||||||
|
init_seq<=init_seq+5'd1;
|
||||||
|
driver_state<=8'd12;
|
||||||
|
write_req<=1'b0;
|
||||||
|
end else begin
|
||||||
|
write_req<=1'b1;
|
||||||
|
end
|
||||||
end else if(col==6'd20)begin
|
end else if(col==6'd20)begin
|
||||||
/** Check if we run out of screen **/
|
/** Check if we run out of screen **/
|
||||||
data<=4'hf;
|
driver_state<=8'd6;
|
||||||
write_req<=1'b1;
|
|
||||||
cmd_data<=1'b0;
|
cmd_data<=1'b0;
|
||||||
data_write_wait_counter<=6'd50;
|
|
||||||
driver_state<=8'd2;
|
|
||||||
next_line<=1;
|
next_line<=1;
|
||||||
end else if(data_write_req==1)begin
|
end else if(data_write_req==1)begin
|
||||||
if(in_ascii_data==8'h0a)begin
|
if(in_ascii_data==8'h0A)begin
|
||||||
data<=4'hf;
|
driver_state<=8'd6;
|
||||||
cmd_data<=1'b0;
|
cmd_data<=1'b0;
|
||||||
write_req<=1'b1;
|
|
||||||
driver_state<=8'd2;
|
|
||||||
next_line<=1;
|
next_line<=1;
|
||||||
end else if(in_ascii_data==8'h0d)begin
|
end else if(in_ascii_data==8'h0D)begin
|
||||||
data<=4'hf;
|
driver_state<=8'd6;
|
||||||
cmd_data<=1'b0;
|
cmd_data<=1'b0;
|
||||||
write_req<=1'b1;
|
|
||||||
driver_state<=8'd2;
|
|
||||||
next_line<=0;
|
next_line<=0;
|
||||||
end else begin
|
end else begin
|
||||||
cmd_data<=1'b1;
|
if (in_ascii_data[7:5]==3'b000||in_ascii_data[7:7]==1'b1)
|
||||||
|
if(in_ascii_data==8'h00)
|
||||||
|
print_data<=8'h23;
|
||||||
|
else
|
||||||
|
print_data<=8'h3F;
|
||||||
|
else
|
||||||
print_data<=in_ascii_data;
|
print_data<=in_ascii_data;
|
||||||
|
cmd_data<=1'b1;
|
||||||
driver_state<=8'd9;
|
driver_state<=8'd9;
|
||||||
end
|
end
|
||||||
in_data_ready<=0;
|
in_data_ready<=0;
|
||||||
end else begin
|
end else begin
|
||||||
in_data_ready<=1;
|
in_data_ready<=1;
|
||||||
end
|
end
|
||||||
end else begin
|
|
||||||
write_req<=1'b0;
|
|
||||||
in_data_ready<=0;
|
|
||||||
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
|
end
|
||||||
8'd1:begin
|
8'd1:begin
|
||||||
if(done_writing==1)
|
if(done_writing==1)
|
||||||
@ -138,8 +152,6 @@ always @(posedge clock,negedge rst_n) begin
|
|||||||
end
|
end
|
||||||
8'd2:begin
|
8'd2:begin
|
||||||
data<=4'hE;
|
data<=4'hE;
|
||||||
cmd_data<=1'b0;
|
|
||||||
data_write_wait_counter<=6'd50;
|
|
||||||
if(!done_writing)begin
|
if(!done_writing)begin
|
||||||
driver_state<=8'd3;
|
driver_state<=8'd3;
|
||||||
write_req<=1'b0;
|
write_req<=1'b0;
|
||||||
@ -153,7 +165,6 @@ always @(posedge clock,negedge rst_n) begin
|
|||||||
8'd4:begin
|
8'd4:begin
|
||||||
data<=4'h0;
|
data<=4'h0;
|
||||||
cmd_data<=1'b0;
|
cmd_data<=1'b0;
|
||||||
data_write_wait_counter<=6'd50;
|
|
||||||
if(!done_writing)begin
|
if(!done_writing)begin
|
||||||
driver_state<=8'd5;
|
driver_state<=8'd5;
|
||||||
write_req<=1'b0;
|
write_req<=1'b0;
|
||||||
@ -164,6 +175,8 @@ always @(posedge clock,negedge rst_n) begin
|
|||||||
if(done_writing==1)
|
if(done_writing==1)
|
||||||
driver_state<=8'd6;
|
driver_state<=8'd6;
|
||||||
end
|
end
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
|
||||||
8'd6:begin
|
8'd6:begin
|
||||||
if(next_line)begin
|
if(next_line)begin
|
||||||
case(line)
|
case(line)
|
||||||
@ -174,14 +187,13 @@ always @(posedge clock,negedge rst_n) begin
|
|||||||
endcase
|
endcase
|
||||||
end else begin
|
end else begin
|
||||||
case(line)
|
case(line)
|
||||||
2'd0: data<=4'h0;
|
2'd0: data<=4'h8;
|
||||||
2'd1: data<=4'hC;
|
2'd1: data<=4'hC;
|
||||||
2'd2: data<=4'h9;
|
2'd2: data<=4'h9;
|
||||||
2'd3: data<=4'hD;
|
2'd3: data<=4'hD;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
data_write_wait_counter<=6'd50;
|
if(done_writing==0)begin
|
||||||
if(!done_writing)begin
|
|
||||||
driver_state<=8'd7;
|
driver_state<=8'd7;
|
||||||
write_req<=1'b0;
|
write_req<=1'b0;
|
||||||
end else
|
end else
|
||||||
@ -207,10 +219,8 @@ always @(posedge clock,negedge rst_n) begin
|
|||||||
2'd3: begin data<=4'h4; ; end
|
2'd3: begin data<=4'h4; ; end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
cmd_data<=1'b0;
|
|
||||||
data_write_wait_counter<=6'd50;
|
|
||||||
if(!done_writing)begin
|
if(!done_writing)begin
|
||||||
driver_state<=8'd0;
|
driver_state<=8'd12;
|
||||||
col<=0;
|
col<=0;
|
||||||
write_req<=1'b0;
|
write_req<=1'b0;
|
||||||
if(next_line)begin
|
if(next_line)begin
|
||||||
@ -221,12 +231,12 @@ always @(posedge clock,negedge rst_n) begin
|
|||||||
2'd3: begin line<=3; end
|
2'd3: begin line<=3; end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
write_req<=1'b0;
|
||||||
end else
|
end else
|
||||||
write_req<=1'b1;
|
write_req<=1'b1;
|
||||||
end
|
end
|
||||||
8'd9:begin
|
8'd9:begin
|
||||||
data<=print_data[7:4];
|
data<=print_data[7:4];
|
||||||
data_write_wait_counter<=6'd50;
|
|
||||||
if(!done_writing)begin
|
if(!done_writing)begin
|
||||||
driver_state<=8'd10;
|
driver_state<=8'd10;
|
||||||
write_req<=1'b0;
|
write_req<=1'b0;
|
||||||
@ -239,17 +249,20 @@ always @(posedge clock,negedge rst_n) begin
|
|||||||
end
|
end
|
||||||
8'd11:begin
|
8'd11:begin
|
||||||
data<=print_data[3:0];
|
data<=print_data[3:0];
|
||||||
data_write_wait_counter<=6'd50;
|
|
||||||
if(!done_writing)begin
|
if(!done_writing)begin
|
||||||
driver_state<=8'd0;
|
driver_state<=8'd12;
|
||||||
write_req<=1'b0;
|
write_req<=1'b0;
|
||||||
col<=col+1;
|
col<=col+1;
|
||||||
end else
|
end else
|
||||||
write_req<=1'b1;
|
write_req<=1'b1;
|
||||||
end
|
end
|
||||||
|
8'd12:begin
|
||||||
|
if(done_writing)
|
||||||
|
driver_state<=8'd0;
|
||||||
|
end
|
||||||
default: begin driver_state<=0; end
|
default: begin driver_state<=0; end
|
||||||
endcase
|
endcase
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user