Blame | Last modification | View Log | Download | RSS feed
// (c) 2010 NedoPC//// fpga SPI slave device.`include "../include/tune.v"module slavespi(input wire fclk,input wire rst_n,input wire spics_n, // avr SPI ifaceoutput wire spidi, //input wire spido, //input wire spick, //input wire [ 7:0] status_in, // status bits to be shown to avroutput wire [39:0] kbd_out,output wire kbd_stb,output wire [ 7:0] mus_out,output wire mus_xstb,output wire mus_ystb,output wire mus_btnstb,output wire kj_stb,input wire [ 7:0] gluclock_addr,input wire [ 2:0] comport_addr,input wire [ 7:0] wait_write,output wire [ 7:0] wait_read,input wire wait_rnw,output wire wait_end,output wire [ 7:0] config0, // config bits for overall systemoutput wire genrst, // positive pulse, causes Z80 resetoutput wire [1:0] rstrom // number of ROM page to reset to);`ifdef SIMULATEinitialbeginforce wait_read = 8'hFF;end`endif// re-synchronize SPI//reg [2:0] spics_n_sync;reg [1:0] spido_sync;reg [2:0] spick_sync;//always @(posedge fclk)beginspics_n_sync[2:0] <= { spics_n_sync[1:0], spics_n };spido_sync [1:0] <= { spido_sync [0], spido };spick_sync [2:0] <= { spick_sync [1:0], spick };end//wire scs_n = spics_n_sync[1]; // scs_n - synchronized CS_Nwire sdo = spido_sync[1];wire sck = spick_sync[1];//wire scs_n_01 = (~spics_n_sync[2]) & spics_n_sync[1] ;wire scs_n_10 = spics_n_sync[2] & (~spics_n_sync[1]);//wire sck_01 = (~spick_sync[2]) & spick_sync[1] ;wire sck_10 = spick_sync[2] & (~spick_sync[1]);reg [7:0] regnum; // register number holderreg [7:0] shift_out;reg [7:0] data_in;// register selectorswire sel_kbdreg, sel_kbdstb, sel_musxcr, sel_musycr, sel_musbtn, sel_kj;wire sel_rstreg, sel_waitreg, sel_gluadr, sel_comadr, sel_cfg0;// keyboard registerreg [39:0] kbd_reg;// mouse registerreg [7:0] mouse_buf;// reset registerreg [7:0] rst_reg;// wait data out registerreg [7:0] wait_reg;//reg [7:0] cfg0_reg_in, cfg0_reg_out; // one for shifting, second for storing values`ifdef SIMULATEinitialbeginrst_reg[5:4] = 2'b00;cfg0_reg_out[7:0] = 8'd0;end`endif// register number//always @(posedge fclk)beginif( scs_n_01 )beginregnum <= 8'd0;endelse if( scs_n && sck_01 )beginregnum[7:0] <= { sdo, regnum[7:1] };endend// send data to avr//always @*beginif( sel_waitreg )data_in = wait_write;else if( sel_gluadr )data_in = gluclock_addr;else if( sel_comadr )data_in = comport_addr;else data_in = 8'hFF;end//always @(posedge fclk)beginif( scs_n_01 || scs_n_10 ) // both edgesbeginshift_out <= scs_n ? status_in : data_in;endelse if( sck_01 )beginshift_out[7:0] <= { 1'b0, shift_out[7:1] };endend//assign spidi = shift_out[0];// reg number decoding//assign sel_kbdreg = ( (regnum[7:4]==4'h1) && !regnum[0] ); // $10assign sel_kbdstb = ( (regnum[7:4]==4'h1) && regnum[0] ); // $11//assign sel_musxcr = ( (regnum[7:4]==4'h2) && !regnum[1] && !regnum[0] ); // $20assign sel_musycr = ( (regnum[7:4]==4'h2) && !regnum[1] && regnum[0] ); // $21assign sel_musbtn = ( (regnum[7:4]==4'h2) && regnum[1] && !regnum[0] ); // $22assign sel_kj = ( (regnum[7:4]==4'h2) && regnum[1] && regnum[0] ); // $23//assign sel_rstreg = ( (regnum[7:4]==4'h3) ) ; // $30//assign sel_waitreg = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b00) ); // $40assign sel_gluadr = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b01) ); // $41assign sel_comadr = ( (regnum[7:4]==4'h4) && (regnum[1:0]==2'b10) ); // $42//assign sel_cfg0 = (regnum[7:4]==4'h5); // $50// registers data-in//always @(posedge fclk)beginif( !scs_n && sel_kbdreg && sck_01 )kbd_reg[39:0] <= { sdo, kbd_reg[39:1] };if( !scs_n && (sel_musxcr || sel_musycr || sel_musbtn || sel_kj) && sck_01 )mouse_buf[7:0] <= { sdo, mouse_buf[7:1] };if( !scs_n && sel_rstreg && sck_01 )rst_reg[7:0] <= { sdo, rst_reg[7:1] };if( !scs_n && sel_waitreg && sck_01 )wait_reg[7:0] <= { sdo, wait_reg[7:1] };if( !scs_n && sel_cfg0 && sck_01 )cfg0_reg_in[7:0] <= { sdo, cfg0_reg_in[7:1] };if( scs_n_01 && sel_cfg0 )cfg0_reg_out <= cfg0_reg_in;end// output dataassign kbd_out = kbd_reg;assign kbd_stb = sel_kbdstb && scs_n_01;assign mus_out = mouse_buf;assign mus_xstb = sel_musxcr && scs_n_01;assign mus_ystb = sel_musycr && scs_n_01;assign mus_btnstb = sel_musbtn && scs_n_01;assign kj_stb = sel_kj && scs_n_01;assign genrst = sel_rstreg && scs_n_01;assign rstrom = rst_reg[5:4];assign wait_read = wait_reg;assign wait_end = sel_waitreg && scs_n_01;assign config0 = cfg0_reg_out;endmodule