module mkm_refdes ( output [3:0] leds, // {blue, red, yellow, green} input mkm_cs_n, mkm_sclk, mkm_di, output mkm_do, input btn_panic ); // // Internal High-Speed Oscillator // wire clk_osc_lf; // 48 MHz SB_LFOSC SB_LFOSC_inst ( .CLKLFPU (1'b1), .CLKLFEN (1'b1), .CLKLF (clk_osc_lf) ) /* synthesis ROUTE_THROUGH_FABRIC = 0 */; // // Blinking Green LED // reg [13:0] led_cnt = 14'd0; reg led_green = 1'b0; always @(posedge clk_osc_lf) begin led_cnt <= led_cnt + 1'b1; led_green <= &led_cnt[13:12]; end // // "Panic" Red LED // reg led_red = 1'b0; always @(posedge clk_osc_lf) led_red <= btn_panic; // // Blue LED to indicate MKM access over SPI // reg led_blue = 1'b0; reg mkm_cs_n_sync1 = 1'b1; reg mkm_cs_n_sync2 = 1'b1; always @(posedge clk_osc_lf) {mkm_cs_n_sync1, mkm_cs_n_sync2} <= {mkm_cs_n, mkm_cs_n_sync1}; reg [12:0] spi_cnt = 13'd0; always @(posedge clk_osc_lf) // if (spi_cnt > 13'd0) spi_cnt <= spi_cnt - 13'd1; else if (!mkm_cs_n_sync2) spi_cnt <= {13{1'b1}}; always @(posedge clk_osc_lf) // led_blue <= spi_cnt[10]; // // serial memory follows // // // operation mode // reg [1:0] opmode = 2'b00; // // bit counter // localparam integer BIT_CNT_W = 16; localparam [BIT_CNT_W-1:0] bit_cnt_zero = {BIT_CNT_W{1'b0}}; reg [BIT_CNT_W-1:0] bit_cnt = bit_cnt_zero; wire [BIT_CNT_W-1:0] bit_cnt_next = bit_cnt + 16'd1; always @(posedge mkm_sclk or posedge mkm_cs_n) // if (mkm_cs_n) bit_cnt <= bit_cnt_zero; else bit_cnt <= bit_cnt_next; // // input shifter // reg [15:0] di_shreg; always @(posedge mkm_sclk) // if (!mkm_cs_n) di_shreg <= {di_shreg[14:0], mkm_di}; // // instruction decoder // reg [7:0] instr_latch; wire instr_is_read = instr_latch == 8'b0000_0011; wire instr_is_write = instr_latch == 8'b0000_0010; wire instr_is_rdsr = instr_latch == 8'b0000_0101; wire instr_is_wrsr = instr_latch == 8'b0000_0001; always @(posedge mkm_sclk) // if (bit_cnt == 7) instr_latch <= {di_shreg[6:0], mkm_di}; // // address latch // reg [15:0] addr_latch; always @(posedge mkm_sclk) begin // if (bit_cnt == 23) addr_latch <= {di_shreg[14:0], mkm_di}; // if ((bit_cnt >= 31) && (bit_cnt[2:0] == 3'b111) & instr_is_write) begin // if (opmode == 2'b10) // page mode addr_latch[4:0] <= addr_latch[4:0] + 1'b1; else if (opmode == 2'b01) // seq mode addr_latch[7:0] <= addr_latch[7:0] + 1'b1; // end // if ((bit_cnt >= 24) && (bit_cnt[2:0] == 3'b000) && instr_is_read) begin // if (opmode == 2'b10) // page addr_latch[4:0] <= addr_latch[4:0] + 1'b1; else if (opmode == 2'b01) // seq addr_latch[7:0] <= addr_latch[7:0] + 1'b1; end // end // // mode change // always @(posedge mkm_sclk) // if ((bit_cnt == 15) && instr_is_wrsr && (di_shreg[4:0] == {5{1'b0}})) // opmode <= di_shreg[6:5]; // // memory // localparam MEM_ADDR_W = 6; // 64 bytes reg [7:0] sram[0:2**MEM_ADDR_W-1] /* synthesis syn_ramstyle="registers" */; // // write logic // always @(posedge mkm_sclk) // if ((bit_cnt >= 31) && (bit_cnt[2:0] == 3'b111) & instr_is_write) // sram[addr_latch[MEM_ADDR_W-1:0]] <= {di_shreg[6:0], mkm_di}; // // serial output // reg [7:0] do_shreg; assign mkm_do = do_shreg[7]; always @(negedge mkm_sclk) // if (bit_cnt[2:0] == 3'b000) begin // if ((bit_cnt >= 24) && instr_is_read) // do_shreg <= sram[addr_latch[MEM_ADDR_W:0]]; // else if ((bit_cnt > 7) && instr_is_rdsr) do_shreg <= {opmode, 5'b00000, 1'b1}; // end else do_shreg <= {do_shreg[6:0], 1'bX}; // // Map LEDs // assign leds[0] = led_green; // assign leds[1] = 1'b0; // unused (yellow) assign leds[2] = led_red; // assign leds[3] = led_blue; // endmodule