From 96c8556d4ceff6ec23f0d392e008fcb56e8612bc Mon Sep 17 00:00:00 2001 From: harbaum Date: Tue, 17 Mar 2015 20:53:24 +0000 Subject: [PATCH] [SPECTRUM] Added new source files --- cores/spectrum/divmmc.v | 109 ++++++++++++++++++++++++++++++++++++++++ cores/spectrum/spi.v | 74 +++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 cores/spectrum/divmmc.v create mode 100644 cores/spectrum/spi.v diff --git a/cores/spectrum/divmmc.v b/cores/spectrum/divmmc.v new file mode 100644 index 0000000..875562f --- /dev/null +++ b/cores/spectrum/divmmc.v @@ -0,0 +1,109 @@ +// divmmc + +module divmmc ( + input reset_n, + input clk, + input clken, + + // Bus interface + input enable, + input [15:0] a, + input wr_n, + input rd_n, + input mreq_n, + input m1_n, + input [7:0] din, + output [7:0] dout, + + // memory state + output reg paged_in, + output [3:0] sram_page, + output mapram, + output conmem, + + // SD card interface + output reg sd_cs, + output sd_sck, + output sd_mosi, + input sd_miso +); + +reg m1_trigger; + +assign sram_page = ctrl[3:0]; +assign mapram = ctrl[6]; +assign conmem = ctrl[7]; +reg [7:0] ctrl; + +// Control del modulo SPI +reg spi_tx_strobe; +reg spi_rx_strobe; + +reg [7:0] acc_cnt /* synthesis noprune */; +always @(posedge enable or negedge reset_n) begin + if(reset_n == 1'b0) + acc_cnt <= 8'd0; + else + acc_cnt <= acc_cnt + 8'd1; +end + +always @(posedge clk) begin + if(reset_n == 1'b0) begin + m1_trigger <= 1'b0; + paged_in <= 1'b0; + ctrl <= 8'h00; + end else begin +// if(clken) begin + if (a[3:0]==4'h3 && enable && !wr_n) + ctrl <= din; + + if(a[3:0]==4'h7 && enable && !wr_n) + sd_cs <= din[0]; + + // SPI read + if (enable && a[3:0]==4'hb && wr_n) + spi_rx_strobe = 1'b1; + else + spi_rx_strobe = 1'b0; + + // SPI write + if (enable && a[3:0]==4'hb && !wr_n) + spi_tx_strobe = 1'b1; + else + spi_tx_strobe = 1'b0; + + if (!mreq_n && !rd_n && !m1_n && + ((a==16'h0000) || (a==16'h0008) || (a==16'h0038) || + (a==16'h0066) || (a==16'h04C6) || (a==16'h0562))) begin + // automapper diferido (siguiente ciclo) + m1_trigger <= 1'b1; + end else if (!mreq_n && !rd_n && !m1_n && a[15:8]==8'h3D) begin + // automapper no diferido (ciclo actual) + paged_in <= 1'b1; + m1_trigger <= 1'b1; + end else if (!mreq_n && !rd_n && !m1_n && a[15:3]==13'b0001111111111) begin + // desconexin de automapper diferido + m1_trigger <= 1'b0; + end + + if (m1_n==1'b1) begin // tras el ciclo M1, aqu es cuando realmente se hace el mapping + paged_in <= m1_trigger; + end +// end + end +end + +// Instanciacion del modulo SPI +spi mi_spi ( + .clk(clk), + .tx_strobe(spi_tx_strobe), + .rx_strobe(spi_rx_strobe), + .din(din), + .dout(dout), + + .spi_clk(sd_sck), + .spi_di(sd_mosi), + .spi_do(sd_miso) +); + +endmodule diff --git a/cores/spectrum/spi.v b/cores/spectrum/spi.v new file mode 100644 index 0000000..78caec9 --- /dev/null +++ b/cores/spectrum/spi.v @@ -0,0 +1,74 @@ +module spi ( + input wire clk, // 7MHz + input wire tx_strobe, // a 1 para indicar que queremos enviar un dato por SPI + input wire rx_strobe,// a 1 para indicar que queremos recibir un dato + input wire [7:0] din, // del bus de datos de salida de la CPU + output reg [7:0] dout, // al bus de datos de entrada de la CPU + + output wire spi_clk, // Interface SPI + output wire spi_di, // + input wire spi_do // + ); + + // Modulo SPI. + reg ciclo_lectura = 1'b0; // ciclo de lectura en curso + reg ciclo_escritura = 1'b0; // ciclo de escritura en curso + reg [4:0] contador = 5'b00000; // contador del FSM (ciclos) + reg [7:0] data_to_spi; // dato a enviar a la spi por DI + reg [7:0] data_from_spi; // dato a recibir desde la spi + reg [7:0] data_to_cpu; // ultimo dato recibido correctamente + + assign spi_clk = contador[0]; // spi_CLK es la mitad que el reloj del módulo + assign spi_di = data_to_spi[7]; // la transmisión es del bit 7 al 0 + + always @(posedge clk) begin + if (tx_strobe && !ciclo_escritura) begin // si ha sido señalizado, iniciar ciclo de escritura + ciclo_escritura <= 1'b1; + ciclo_lectura <= 1'b0; + contador <= 5'b00000; + data_to_spi <= din; + end + else if (rx_strobe && !ciclo_lectura) begin // si no, si mirar si hay que iniciar ciclo de lectura + ciclo_lectura <= 1'b1; + ciclo_escritura <= 1'b0; + contador <= 5'b00000; + data_to_cpu <= data_from_spi; + data_from_spi <= 8'h00; + data_to_spi <= 8'hFF; // mientras leemos, MOSI debe estar a nivel alto! + end + + // FSM para enviar un dato a la spi + else if (ciclo_escritura==1'b1) begin + if (contador!=5'b10000) begin + if (spi_clk==1'b1) begin + data_to_spi <= {data_to_spi[6:0],1'b0}; + data_from_spi <= {data_from_spi[6:0],spi_do}; + end + contador <= contador + 1; + end + else begin + if (!tx_strobe) + ciclo_escritura <= 1'b0; + end + end + + // FSM para leer un dato de la spi + else if (ciclo_lectura==1'b1) begin + if (contador!=5'b10000) begin + if (spi_clk==1'b1) + data_from_spi <= {data_from_spi[6:0],spi_do}; + contador <= contador + 1; + end + else begin + if (!rx_strobe) + ciclo_lectura <= 1'b0; + end + end + end + + always @* begin + if (rx_strobe) begin + dout = data_to_cpu; + end + end +endmodule