1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-06 08:04:41 +00:00

[Archie] Use only clk_32 in user_io and ioc

This commit is contained in:
Gyorgy Szombathelyi
2019-02-08 21:24:39 +01:00
parent 7472f9339d
commit 8d83a61d1d
3 changed files with 142 additions and 126 deletions

View File

@@ -59,18 +59,6 @@ module archimedes_mist_top(
input CONF_DATA0 // SPI_SS for user_io
);
// the configuration string is returned to the io controller to allow
// it to control the menu on the OSD
parameter CONF_STR = {
"ARCHIE;ARCH;",
"O1,MODE,8bbp,4bbp,2bbp,1bbp;",
"T2,Start;",
"T3,Select;",
"T4,Reset;"
};
parameter CONF_STR_LEN = 12+28+9+10+9;
wire [7:0] kbd_out_data;
wire kbd_out_strobe;
wire [7:0] kbd_in_data;
@@ -146,11 +134,10 @@ assign VGA_VS = core_vs;
assign SPI_DO = (CONF_DATA0==0)?user_io_sdo:(SPI_SS2==0)?data_io_sdo:1'bZ;
wire user_io_sdo;
user_io #(.STRLEN(CONF_STR_LEN)) user_io(
.conf_str ( CONF_STR ),
user_io user_io(
// the spi interface
.SPI_CLK (SPI_SCK ),
.clk_sys ( clk_32m ),
.SPI_CLK (SPI_SCK ),
.SPI_SS_IO (CONF_DATA0 ),
.SPI_MISO (user_io_sdo ), // tristate handling inside user_io
.SPI_MOSI (SPI_DI ),

View File

@@ -22,124 +22,154 @@
// parameter STRLEN and the actual length of conf_str have to match
module user_io #(parameter STRLEN=0) (
input [(8*STRLEN)-1:0] conf_str,
module user_io (
input clk_sys,
input SPI_CLK,
input SPI_SS_IO,
output reg SPI_MISO,
input SPI_MOSI,
input SPI_CLK,
input SPI_SS_IO,
output reg SPI_MISO,
input SPI_MOSI,
output [7:0] JOY0,
output [7:0] JOY1,
output [1:0] BUTTONS,
output [1:0] SWITCHES,
output [7:0] JOY0,
output [7:0] JOY1,
input [7:0] kbd_out_data,
input kbd_out_strobe,
output [7:0] kbd_in_data,
output reg kbd_in_strobe
input [7:0] kbd_out_data,
input kbd_out_strobe,
output reg [7:0] kbd_in_data,
output reg kbd_in_strobe,
output [1:0] BUTTONS,
output [1:0] SWITCHES
);
// kbd in data is valid on rising edge of kbd_in_strobe
assign kbd_in_data = { sbuf, SPI_MOSI };
reg [6:0] sbuf;
reg [7:0] cmd;
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
reg [9:0] byte_cnt; // counts bytes
reg [7:0] but_sw;
reg [6:0] sbuf;
reg [7:0] cmd;
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
reg [7:0] byte_cnt; // counts bytes
reg [7:0] joystick0;
reg [7:0] joystick1;
reg [3:0] but_sw;
reg [31:0] joystick_0;
reg [31:0] joystick_1;
reg [31:0] joystick_2;
reg [31:0] joystick_3;
reg [31:0] joystick_4;
assign JOY0 = joystick0;
assign JOY1 = joystick1;
assign BUTTONS = but_sw[1:0];
assign JOY0 = joystick_0[7:0];
assign JOY1 = joystick_1[7:0];
assign BUTTONS = but_sw[1:0];
assign SWITCHES = but_sw[3:2];
// this variant of user_io is for the achie core (type == a6) only
wire [7:0] core_type = 8'ha6;
reg kbd_out_data_available;
always @(posedge kbd_out_strobe or posedge kbd_out_ack) begin
if(kbd_out_ack) kbd_out_data_available <= 1'b0;
else kbd_out_data_available <= 1'b1;
end
reg [7:0] spi_byte_out;
wire [7:0] kbd_out_status = { 4'ha, 3'b000, kbd_out_data_available };
reg kbd_out_data_available = 0;
// drive MISO only when transmitting core id
always@(negedge SPI_CLK or posedge SPI_SS_IO) begin
if(SPI_SS_IO == 1) begin
SPI_MISO <= 1'bZ;
end else begin
// first byte returned is always core type, further bytes are
// command dependent
if(byte_cnt == 0) begin
SPI_MISO <= core_type[~bit_cnt];
end else begin
// reading keyboard data
if(cmd == 8'h04) begin
if(byte_cnt == 1) SPI_MISO <= kbd_out_status[~bit_cnt];
else SPI_MISO <= kbd_out_data[~bit_cnt];
end
// reading config string
if(cmd == 8'h14) begin
// returning a byte from string
if(byte_cnt < STRLEN + 1)
SPI_MISO <= conf_str[{STRLEN - byte_cnt,~bit_cnt}];
else
SPI_MISO <= 1'b0;
end
end
end
// SPI bit and byte counters
always@(posedge SPI_CLK or posedge SPI_SS_IO) begin
if(SPI_SS_IO == 1) begin
bit_cnt <= 0;
byte_cnt <= 0;
end else begin
if((bit_cnt == 7)&&(~&byte_cnt)) begin
byte_cnt <= byte_cnt + 8'd1;
if (!byte_cnt) cmd <= {sbuf, SPI_MOSI};
end
bit_cnt <= bit_cnt + 1'd1;
end
end
// SPI receiver
reg kbd_out_ack;
always@(negedge SPI_CLK or posedge SPI_SS_IO) begin
if(SPI_SS_IO == 1) begin
SPI_MISO <= 1'bZ;
end else begin
// first byte returned is always core type, further bytes are
// command dependent
if(byte_cnt == 0) begin
SPI_MISO <= core_type[~bit_cnt];
end else begin
// reading keyboard data
if(cmd == 8'h04) begin
if(byte_cnt == 1) SPI_MISO <= kbd_out_status[~bit_cnt];
else SPI_MISO <= kbd_out_data[~bit_cnt];
end
end
end
end
// SPI receiver IO -> FPGA
reg spi_receiver_strobe_r = 0;
reg spi_transfer_end_r = 1;
reg [7:0] spi_byte_in;
// Read at spi_sck clock domain, assemble bytes for transferring to clk_sys
always@(posedge SPI_CLK or posedge SPI_SS_IO) begin
if(SPI_SS_IO == 1) begin
bit_cnt <= 3'd0;
byte_cnt <= 8'd0;
kbd_out_ack <= 1'b0;
kbd_in_strobe <= 1'b0;
end else begin
kbd_out_ack <= 1'b0;
kbd_in_strobe <= 1'b0;
if(SPI_SS_IO == 1) begin
spi_transfer_end_r <= 1;
end else begin
spi_transfer_end_r <= 0;
bit_cnt <= bit_cnt + 3'd1;
if(bit_cnt == 7) byte_cnt <= byte_cnt + 8'd1;
else sbuf[6:0] <= { sbuf[5:0], SPI_MOSI };
if(bit_cnt != 7)
sbuf[6:0] <= { sbuf[5:0], SPI_MOSI };
// finished reading command byte
if(bit_cnt == 7) begin
if(byte_cnt == 0)
cmd <= { sbuf, SPI_MOSI};
if(byte_cnt != 0) begin
if(cmd == 8'h01)
but_sw <= { sbuf[2:0], SPI_MOSI };
if(cmd == 8'h02)
joystick0 <= { sbuf, SPI_MOSI };
if(cmd == 8'h03)
joystick1 <= { sbuf, SPI_MOSI };
// KBD_OUT status byte has been read
if((cmd == 8'h04) && (byte_cnt == 1))
kbd_out_ack <= 1'b1;
// KBD_IN data byte
if((cmd == 8'h05) && (byte_cnt == 1))
kbd_in_strobe <= 1'b1;
end
end
end
// finished reading a byte, prepare to transfer to clk_sys
if(bit_cnt == 7) begin
spi_byte_in <= { sbuf, SPI_MOSI};
spi_receiver_strobe_r <= ~spi_receiver_strobe_r;
end
end
end
// Process bytes from SPI at the clk_sys domain
always @(posedge clk_sys) begin
reg spi_receiver_strobe;
reg spi_transfer_end;
reg spi_receiver_strobeD;
reg spi_transfer_endD;
reg [7:0] acmd;
reg [7:0] abyte_cnt; // counts bytes
kbd_in_strobe <= 0;
//synchronize between SPI and sys clock domains
spi_receiver_strobeD <= spi_receiver_strobe_r;
spi_receiver_strobe <= spi_receiver_strobeD;
spi_transfer_endD <= spi_transfer_end_r;
spi_transfer_end <= spi_transfer_endD;
// strobe is set whenever a valid byte has been received
if (~spi_transfer_endD & spi_transfer_end) begin
abyte_cnt <= 8'd0;
end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin
if(~&abyte_cnt)
abyte_cnt <= abyte_cnt + 8'd1;
if(abyte_cnt == 0) begin
acmd <= spi_byte_in;
end else begin
case(acmd)
// buttons and switches
8'h01: but_sw <= spi_byte_in;
8'h60: if (abyte_cnt < 5) joystick_0[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h61: if (abyte_cnt < 5) joystick_1[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h62: if (abyte_cnt < 5) joystick_2[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h63: if (abyte_cnt < 5) joystick_3[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h64: if (abyte_cnt < 5) joystick_4[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
8'h04: if (abyte_cnt == 1) kbd_out_data_available <= 0;
8'h05: if (abyte_cnt == 1) begin
kbd_in_strobe <= 1;
kbd_in_data <= spi_byte_in;
end
endcase
end
end
if (kbd_out_strobe) kbd_out_data_available <= 1;
end
endmodule

View File

@@ -88,18 +88,17 @@ wire read_request = (wb_bank == 3'b000) & wb_stb & wb_cyc & !wb_we;
// keyboard input is valid on rising edge of kbd_in_strobe. Latch data then
// and set irq
reg [7:0] kbd_in_data_latch;
always @(posedge kbd_in_strobe)
kbd_in_data_latch <= kbd_in_data;
// input data irq is cleared when cpu reads input port
reg kbd_in_irq_ack;
reg kbd_in_irq;
always @(posedge kbd_in_strobe or posedge kbd_in_irq_ack) begin
if(kbd_in_irq_ack) kbd_in_irq <= 1'b0;
else kbd_in_irq <= 1'b1;
// input data irq is cleared when cpu reads input port
always @(posedge clkcpu or posedge kbd_in_irq_ack) begin
if (kbd_in_irq_ack) kbd_in_irq <= 0;
else if (kbd_in_strobe) begin
kbd_in_data_latch <= kbd_in_data;
kbd_in_irq <= 1;
end
end
// faked kbd tx timing
reg[4:0] txcount = 5'd0;
wire txdone = txcount == 5'd0 /* synthesis keep */;