123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- /*
- * top.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
- * SPDX-License-Identifier: CERN-OHL-P-2.0
- */
- `default_nettype none
- `include "boards.vh"
- module top (
- // SPI
- inout wire spi_mosi,
- inout wire spi_miso,
- inout wire spi_clk,
- output wire spi_flash_cs_n,
- `ifdef HAS_PSRAM
- output wire spi_ram_cs_n,
- `endif
- // USB TODO: remove later
- inout wire usb_dp,
- inout wire usb_dn,
- output wire usb_pu,
- // Debug UART
- input wire uart_rx,
- output wire uart_tx,
- // Buttons (2 for now to test up and down)
- input wire btn_n,
- input wire btn_1,
- input wire btn_2,
- // LEDs to blink to show that a value change has been registered?
- output wire[4:0] led,
- // GPIOs for out signal
- output wire out1,
- output wire out2,
- output wire out3,
- // LED TODO: remove later
- output wire [2:0] rgb,
- // Clock
- input wire clk_in
- );
- localparam integer SPRAM_AW = 14; /* 14 => 64k, 15 => 128k */
- localparam integer WB_N = 7; // TODO: Reduce
- localparam integer WB_DW = 32;
- localparam integer WB_AW = 16;
- localparam integer WB_RW = WB_DW * WB_N;
- localparam integer WB_MW = WB_DW / 8;
- localparam integer FAST_PWM_WIDTH = 8;
- localparam integer PULSE_COUNTER_WIDTH = 8;
- localparam integer SLOW_PWM_WIDTH = 14;
- genvar i;
- // Signals
- // -------
- // Wishbone
- wire [WB_AW-1:0] wb_addr;
- wire [WB_DW-1:0] wb_rdata [0:WB_N-1];
- wire [WB_RW-1:0] wb_rdata_flat;
- wire [WB_DW-1:0] wb_wdata;
- wire [WB_MW-1:0] wb_wmsk;
- wire [WB_N -1:0] wb_cyc;
- wire wb_we;
- wire [WB_N -1:0] wb_ack;
- // WarmBoot
- reg boot_now;
- reg [1:0] boot_sel;
- // Clock / Reset logic
- wire clk_24m;
- wire clk_48m;
- wire rst;
- // 3 signal
- wire [SLOW_PWM_WIDTH-1:0] period1;
- wire [SLOW_PWM_WIDTH-1:0] delay1;
- wire [SLOW_PWM_WIDTH-1:0] duty2;
- wire [SLOW_PWM_WIDTH-1:0] delay2;
- wire [FAST_PWM_WIDTH-1:0] period3;
- wire [FAST_PWM_WIDTH-1:0] duty3;
- wire [SLOW_PWM_WIDTH-1:0] delay3;
- wire [PULSE_COUNTER_WIDTH-1:0] npuls3;
- wire [1:0] odd_train_flag;
- wire ena_odd_out3;
- // Mailbox signal wires
- wire [16*16-1:0] mailbox_regs_flat; // Flattened register array (16 registers of 16 bits each)
- // SoC
- // ---
- soc_picorv32_base #(
- .WB_N (WB_N),
- .WB_DW (WB_DW),
- .WB_AW (WB_AW),
- .SPRAM_AW(SPRAM_AW)
- ) base_I (
- .wb_addr (wb_addr),
- .wb_rdata(wb_rdata_flat),
- .wb_wdata(wb_wdata),
- .wb_wmsk (wb_wmsk),
- .wb_we (wb_we),
- .wb_cyc (wb_cyc),
- .wb_ack (wb_ack),
- .clk (clk_24m),
- .rst (rst)
- );
- for (i=0; i<WB_N; i=i+1)
- assign wb_rdata_flat[i*WB_DW+:WB_DW] = wb_rdata[i];
- // UART [1]
- // ----
- uart_wb #(
- .DIV_WIDTH(12),
- .DW(WB_DW)
- ) uart_I (
- .uart_tx (uart_tx),
- .uart_rx (uart_rx),
- .wb_addr (wb_addr[1:0]),
- .wb_rdata (wb_rdata[1]),
- .wb_we (wb_we),
- .wb_wdata (wb_wdata),
- .wb_cyc (wb_cyc[1]),
- .wb_ack (wb_ack[1]),
- .clk (clk_24m),
- .rst (rst)
- );
- // SPI [2]
- // ---
- ice40_spi_wb #(
- `ifdef HAS_PSRAM
- .N_CS(2),
- `else
- .N_CS(1),
- `endif
- .WITH_IOB(1),
- .UNIT(0)
- ) spi_I (
- .pad_mosi (spi_mosi),
- .pad_miso (spi_miso),
- .pad_clk (spi_clk),
- `ifdef HAS_PSRAM
- .pad_csn ({spi_ram_cs_n, spi_flash_cs_n}),
- `else
- .pad_csn (spi_flash_cs_n),
- `endif
- .wb_addr (wb_addr[3:0]),
- .wb_rdata (wb_rdata[2]),
- .wb_wdata (wb_wdata),
- .wb_we (wb_we),
- .wb_cyc (wb_cyc[2]),
- .wb_ack (wb_ack[2]),
- .clk (clk_24m),
- .rst (rst)
- );
- // RGB LEDs [3]
- // --------
- ice40_rgb_wb #(
- .CURRENT_MODE("0b1"),
- .RGB0_CURRENT("0b000001"),
- .RGB1_CURRENT("0b000001"),
- .RGB2_CURRENT("0b000001")
- ) rgb_I (
- .pad_rgb (rgb),
- .wb_addr (wb_addr[4:0]),
- .wb_rdata (wb_rdata[3]),
- .wb_wdata (wb_wdata),
- .wb_we (wb_we),
- .wb_cyc (wb_cyc[3]),
- .wb_ack (wb_ack[3]),
- .clk (clk_24m),
- .rst (rst)
- );
- // USB [4 & 5]
- // ---
- soc_usb #(
- .DW(WB_DW)
- ) usb_I (
- .usb_dp (usb_dp),
- .usb_dn (usb_dn),
- .usb_pu (usb_pu),
- .wb_addr (wb_addr[11:0]),
- .wb_rdata (wb_rdata[4]),
- .wb_wdata (wb_wdata),
- .wb_we (wb_we),
- .wb_cyc (wb_cyc[5:4]),
- .wb_ack (wb_ack[5:4]),
- .clk_sys (clk_24m),
- .clk_48m (clk_48m),
- .rst (rst)
- );
- assign wb_rdata[5] = 0;
- // WB Mailbox [6] TODO: this will move to lower addresses
- // ----------
- mailbox_wb #(
- .AW(4),
- .DW(WB_DW)
- ) mailbox_I (
- .clk(clk_24m),
- .rst(rst),
- .wb_addr(wb_addr[5:2]), // use word instead of byte addressing
- .wb_wdata(wb_wdata),
- .wb_rdata(wb_rdata[6]),
- .wb_we(wb_we),
- .wb_cyc(wb_cyc[6]),
- .wb_ack(wb_ack[6]),
- .registers_flat(mailbox_regs_flat)
- );
- // 3 Signal
- // --------
- assign period1 = mailbox_regs_flat[15:0]; // First 16 bits for period1
- assign delay1 = mailbox_regs_flat[31:16]; // Next 16 bits for delay1
- assign duty2 = mailbox_regs_flat[47:32]; // Next 16 bits for duty2
- assign delay2 = mailbox_regs_flat[63:48]; // Next 16 bits for delay2
- assign period3 = mailbox_regs_flat[79:64]; // Next 16 bits for period3
- assign duty3 = mailbox_regs_flat[95:80]; // Next 16 bits for duty3
- assign delay3 = mailbox_regs_flat[111:96]; // Next 16 bits for delay3
- assign npuls3 = mailbox_regs_flat[127:112]; // Next 16 bits for npuls3
- assign odd_train_flag = mailbox_regs_flat[143:128]; // Next 16 bits for odd_train_flag
- assign ena_odd_out3 = mailbox_regs_flat[159:144]; // Next 16 bits for ena_odd_out3
- three_signal #(
- .FAST_PWM_WIDTH(FAST_PWM_WIDTH),
- .PULSE_COUNTER_WIDTH(PULSE_COUNTER_WIDTH),
- .SLOW_PWM_WIDTH(SLOW_PWM_WIDTH)
- ) three_signal_I(
- .nrst(~rst),
- .clk(clk_24m), // TODO: fix later we have CDC problem here
- .period1(period1),
- .delay1(delay1),
- .duty2(duty2),
- .delay2(delay2),
- .period3(period3),
- .duty3(duty3),
- .delay3(delay3),
- .npuls3(npuls3),
- .odd_train_flag(odd_train_flag),
- .ena_odd_out3(ena_odd_out3),
- .Out1(out1),
- .Out2(out2),
- .Out3(out3)
- );
- // TODO: dummy led onoff when value has been written
- always @(posedge clk_24m or posedge rst)
- if (rst) begin
- led[0] = 1'b0;
- led[1] = 1'b0;
- led[2] = 1'b0;
- end else if (period1 == 1) begin
- led[0] = 1'b1;
- led[1] = 1'b0;
- led[2] = 1'b0;
- end else if (period1 == 2) begin
- led[0] = 1'b0;
- led[1] = 1'b1;
- led[2] = 1'b0;
- end else if (period1 == 4) begin
- led[0] = 1'b0;
- led[1] = 1'b0;
- led[2] = 1'b1;
- //end else if (period1 != 0) begin
- // led[0] = 1'b1;
- // led[1] = 1'b1;
- // led[2] = 1'b0;
- end else begin
- led[0] = 1'b0;
- led[1] = 1'b0;
- led[2] = 1'b0;
- end
- always @(posedge clk_24m or posedge rst)
- if (rst) begin
- led[3] = 1'b0;
- end else if (btn_2) begin
- led[3] = 1'b1;
- end else begin
- led[3] = 1'b0;
- end
- //// TODO: dummy driving from delay1
- always @(posedge clk_24m or posedge rst)
- if (rst) begin
- led[4] = 1'b0;
- end else if (delay1 !=0 ) begin
- led[4] = 1'b1;
- end else begin
- led[4] = 1'b0;
- end
- //always @(posedge clk_48m or posedge rst)
- // if (rst) begin
- // led[3] = 1'b0;
- // end else if (delay2 != 0) begin
- // led[3] = 1'b1;
- // end else begin
- // led[3] = 1'b0;
- // end
- // Warm Boot
- // ---------
- // Bus interface
- always @(posedge clk_24m or posedge rst)
- if (rst) begin
- boot_now <= 1'b0;
- boot_sel <= 2'b00;
- end else if (wb_cyc[0] & wb_we & (wb_addr[2:0] == 3'b000)) begin
- boot_now <= wb_wdata[2];
- boot_sel <= wb_wdata[1:0];
- end
- assign wb_rdata[0] = 0;
- assign wb_ack[0] = wb_cyc[0];
- // Helper
- dfu_helper #(
- .TIMER_WIDTH(24),
- .BTN_MODE(3),
- .DFU_MODE(0)
- ) dfu_helper_I (
- .boot_now(boot_now),
- .boot_sel(boot_sel),
- .btn_pad(btn_n),
- .btn_val(),
- .rst_req(),
- .clk(clk_24m),
- .rst(rst)
- );
- // Clock / Reset
- // -------------
- `ifdef SIM
- reg clk_48m_s = 1'b0;
- reg clk_24m_s = 1'b0;
- reg rst_s = 1'b1;
- always #10.42 clk_48m_s <= !clk_48m_s;
- always #20.84 clk_24m_s <= !clk_24m_s;
- initial begin
- #200 rst_s = 0;
- end
- assign clk_48m = clk_48m_s;
- assign clk_24m = clk_24m_s;
- assign rst = rst_s;
- `else
- sysmgr sys_mgr_I (
- .clk_in(clk_in),
- .rst_in(1'b0),
- .clk_48m(clk_48m),
- .clk_24m(clk_24m),
- .rst_out(rst)
- );
- `endif
- endmodule // top
|