module TopLevel (CLKIN, BTN, SWITCH, LED, SEG, ANODE, RX_A, TX_A, SRAM_IO1, SRAM_CE1, SRAM_UB1, SRAM_LB1, SRAM_ADR, SRAM_WE, SRAM_OE, SRAM_IO2, SRAM_CE2, SRAM_UB2, SRAM_LB2); input CLKIN; input [3:0] BTN; input [7:0] SWITCH; output [7:0] LED; output [7:0] SEG; output [3:0] ANODE; input RX_A; output TX_A; output [17:0] SRAM_ADR; output SRAM_WE; output SRAM_OE; inout [15:0] SRAM_IO1; output SRAM_CE1; output SRAM_UB1; output SRAM_LB1; inout [15:0] SRAM_IO2; output SRAM_CE2; output SRAM_UB2; output SRAM_LB2; DCM #( .CLKFX_DIVIDE(2), // Can be any integer from 1 to 32 .CLKFX_MULTIPLY(2), // Can be any integer from 2 to 32 .CLKIN_PERIOD(20.0), // Period of input clock .STARTUP_WAIT("TRUE"), // Delay configuration DONE until DCM LOCK? .CLKDV_DIVIDE(2.0), // [1.5,7.5]/0.5 or [8.0,16.0]/1.0 .CLKIN_DIVIDE_BY_2("FALSE"), // Enable CLKIN divide-by-two feature? .CLKOUT_PHASE_SHIFT("NONE"), // NONE, FIXED or VARIABLE .CLK_FEEDBACK("1X"), // Specify clock feedback of NONE, 1X or 2X .PHASE_SHIFT(0) // Amount of fixed phase shift, -255 to 255 ) DCM0 ( .CLK0(CLK0), // CLKOUT w/ 0 degree shift // .CLK2X(CLK_100), // 2 * CLK0 frequency // .CLKFX(CLKFX), // DCM CLK synthesis out (M/D) .CLKIN(CLKIN), // Clock input (from IBUFG, BUFG or DCM) .CLKFB(CLK0) // DCM clock feedback ); wire CLK_O = CLK0; reg RST_O = 1'b1; wire [31:0] IADR_I; wire [31:0] INST_ADR_O; wire [7:0] INST_DAT_I; wire [31:2] CPU_ADR_O; wire [31:0] CPU_DAT_I; wire [31:0] CPU_DAT_O; wire [3:0] CPU_SEL_O; wire CPU_ACK_I; StackCPU MyStackCPU ( .CLK_I(CLK_O), .RST_I(RST_O), .IRQ_I(IRQ_I), .IADR_I(IADR_I), .IACK_O(IACK_O), .INST_ADR_O(INST_ADR_O), .INST_DAT_I(INST_DAT_I), .INST_CYC_O(INST_CYC_O), .INST_STB_O(INST_STB_O), .INST_ACK_I(INST_ACK_I), .DATA_ADR_O(CPU_ADR_O), .DATA_DAT_I(CPU_DAT_I), .DATA_DAT_O(CPU_DAT_O), .DATA_CYC_O(CPU_CYC_O), .DATA_STB_O(CPU_STB_O), .DATA_WE_O(CPU_WE_O), .DATA_SEL_O(CPU_SEL_O), .DATA_ACK_I(CPU_ACK_I) ); // Bus arbiter master signals wire [31:2] DATA_ADR_O; reg [31:0] DATA_DAT_I; wire [31:0] DATA_DAT_O; wire [3:0] DATA_SEL_O; reg DATA_ACK_I; `define SLV_PROGRAM_RAM 4'b0000 `define SLV_SRAM 4'b0001 `define SLV_IRQ_CTL 4'b0010 `define SLV_DMA_CTL 4'b0011 `define SLV_TIMER 4'b0100 `define SLV_LED_SWITCH 4'b0101 `define SLV_BTN_DISPLAY 4'b0110 `define SLV_RS232 4'b0111 `define SLV_UNUSED 4'b1111 reg [3:0] SLAVE; always @* begin /* casex (DATA_ADR_O) 30'bXXXX_XXXX_XX00_XXXX_XXXX_XXXX_XXXX_XX: SLAVE <= `SLV_PROGRAM_RAM; 30'bXXXX_XXXX_XX01_XXXX_XXXX_XXXX_XXXX_XX: SLAVE <= `SLV_SRAM; 30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X0XX_XX: SLAVE <= `SLV_IRQ_CTL; 30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X10X_XX: SLAVE <= `SLV_DMA_CTL; 30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X110_XX: SLAVE <= `SLV_TIMER; 30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X111_00: SLAVE <= `SLV_LED_SWITCH; 30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X111_01: SLAVE <= `SLV_BTN_DISPLAY; 30'bXXXX_XXXX_XX11_XXXX_XXXX_XXXX_X111_1X: SLAVE <= `SLV_RS232; default: SLAVE <= `SLV_UNUSED; endcase */ // Manually decode the above table, because xst appears to // attempt to expand it rather than ignore the 'X' bits. case (DATA_ADR_O[21:20]) 2'b00: SLAVE <= `SLV_PROGRAM_RAM; 2'b01: SLAVE <= `SLV_SRAM; 2'b10: SLAVE <= `SLV_UNUSED; 2'b11: casex (DATA_ADR_O[6:2]) 5'b0XX_XX: SLAVE <= `SLV_IRQ_CTL; 5'b10X_XX: SLAVE <= `SLV_DMA_CTL; 5'b110_XX: SLAVE <= `SLV_TIMER; 5'b111_00: SLAVE <= `SLV_LED_SWITCH; 5'b111_01: SLAVE <= `SLV_BTN_DISPLAY; 5'b111_1X: SLAVE <= `SLV_RS232; default: SLAVE <= `SLV_UNUSED; endcase endcase end wire [31:0] DMA_CTL_DAT_O; wire [31:2] DMA_SRC_ADR_O; wire [31:0] DMA_SRC_DAT_I; wire [31:2] DMA_DST_ADR_O; wire [31:0] DMA_DST_DAT_O; WB_DMA DMAController ( .CLK_I(CLK_O), .RST_I(RST_O), .IRQ_O(DMA_IRQ_O), .CTL_ADR_I(DATA_ADR_O[3:2]), .CTL_DAT_I(DATA_DAT_O), .CTL_DAT_O(DMA_CTL_DAT_O), .CTL_STB_I(DATA_STB_O & (SLAVE == `SLV_DMA_CTL)), .CTL_WE_I(DATA_WE_O), .CTL_ACK_O(DMA_CTL_ACK_O), .SRC_ADR_O(DMA_SRC_ADR_O), .SRC_DAT_I(DMA_SRC_DAT_I), .SRC_STB_O(DMA_SRC_STB_O), .SRC_WE_O(DMA_SRC_WE_O), .SRC_ACK_I(DMA_SRC_ACK_I), .DST_ADR_O(DMA_DST_ADR_O), .DST_DAT_O(DMA_DST_DAT_O), .DST_STB_O(DMA_DST_STB_O), .DST_WE_O(DMA_DST_WE_O), .DST_ACK_I(DMA_DST_ACK_I) ); wire [31:2] DMA_ADR_O; wire [31:0] DMA_DAT_O; wire [31:0] DMA_DAT_I; wire [3:0] DMA_SEL_O; wire DMA_ACK_I; WB_ARB_2M DMAArbiter ( .CLK_I(CLK_O), .RST_I(RST_O), .M0_ADR_I(DMA_SRC_ADR_O), .M0_DAT_I(32'd0), .M0_DAT_O(DMA_SRC_DAT_I), .M0_LOCK_I(1'b0), .M0_CYC_I(DMA_SRC_STB_O), .M0_STB_I(DMA_SRC_STB_O), .M0_WE_I(DMA_SRC_WE_O), .M0_SEL_I(4'b1111), .M0_ACK_O(DMA_SRC_ACK_I), .M1_ADR_I(DMA_DST_ADR_O), .M1_DAT_I(DMA_DST_DAT_O), .M1_LOCK_I(1'b0), .M1_CYC_I(DMA_DST_STB_O), .M1_STB_I(DMA_DST_STB_O), .M1_WE_I(DMA_DST_WE_O), .M1_SEL_I(4'b1111), .M1_ACK_O(DMA_DST_ACK_I), .S_ADR_O(DMA_ADR_O), .S_DAT_O(DMA_DAT_O), .S_DAT_I(DMA_DAT_I), .S_CYC_O(DMA_CYC_O), .S_STB_O(DMA_STB_O), .S_WE_O(DMA_WE_O), .S_SEL_O(DMA_SEL_O), .S_ACK_I(DMA_ACK_I), .S_ERR_I(1'b0), .S_RTY_I(1'b0) ); WB_ARB_2M BusArbiter ( .CLK_I(CLK_O), .RST_I(RST_O), .M0_ADR_I(CPU_ADR_O), .M0_DAT_I(CPU_DAT_O), .M0_DAT_O(CPU_DAT_I), .M0_LOCK_I(1'b0), .M0_CYC_I(CPU_CYC_O), .M0_STB_I(CPU_STB_O), .M0_WE_I(CPU_WE_O), .M0_SEL_I(CPU_SEL_O), .M0_ACK_O(CPU_ACK_I), .M1_ADR_I(DMA_ADR_O), .M1_DAT_I(DMA_DAT_O), .M1_DAT_O(DMA_DAT_I), .M1_LOCK_I(1'b0), .M1_CYC_I(DMA_CYC_O), .M1_STB_I(DMA_STB_O), .M1_WE_I(DMA_WE_O), .M1_SEL_I(DMA_SEL_O), .M1_ACK_O(DMA_ACK_I), .S_ADR_O(DATA_ADR_O), .S_DAT_O(DATA_DAT_O), .S_DAT_I(DATA_DAT_I), .S_STB_O(DATA_STB_O), .S_WE_O(DATA_WE_O), .S_SEL_O(DATA_SEL_O), .S_ACK_I(DATA_ACK_I), .S_ERR_I(1'b0), .S_RTY_I(1'b0) ); wire [31:0] TIMER_DAT_O; TIMER #( .INIT_RELOAD(32'd49999) ) Timer ( .CLK_I(CLK_O), .RST_I(RST_O), .ADR_I(DATA_ADR_O[3:2]), .DAT_I(DATA_DAT_O), .DAT_O(TIMER_DAT_O), .STB_I(DATA_STB_O & (SLAVE == `SLV_TIMER)), .WE_I(DATA_WE_O), .ACK_O(TIMER_ACK_O), .IRQ_O(TIMER_IRQ_O) ); wire RS232_TX_FULL; wire RS232_RX_EMPTY; wire [31:0] IRQ_DAT_O; IRQ_CTL InterruptController ( .CLK_I(CLK_O), .RST_I(RST_O), .IRQ_O(IRQ_I), .IADR_O(IADR_I), .IACK_I(IACK_O), .ADR_I(DATA_ADR_O[5:2]), .DAT_I(DATA_DAT_O), .DAT_O(IRQ_DAT_O), .STB_I(DATA_STB_O & (SLAVE == `SLV_IRQ_CTL)), .WE_I(DATA_WE_O), .SEL_I(DATA_SEL_O), .ACK_O(IRQ_ACK_O), .IRQ0(1'b0), .IRQ1(~RS232_RX_EMPTY), .IRQ2(DMA_IRQ_O), .IRQ3(~RS232_TX_FULL), .IRQ4(TIMER_IRQ_O), .IRQ5(1'b0), .IRQ6(1'b0), .IRQ7(1'b0) ); wire [31:0] PROGRAM_DAT_O; ProgramRAM Program ( .CLK_I(CLK_O), .RST_I(RST_O), .INST_ADR_I(INST_ADR_O[12:0]), .INST_DAT_O(INST_DAT_I), .INST_STB_I(INST_STB_O), .INST_ACK_O(INST_ACK_I), .DATA_ADR_I(DATA_ADR_O[12:2]), .DATA_DAT_I(DATA_DAT_O), .DATA_DAT_O(PROGRAM_DAT_O), .DATA_STB_I(DATA_STB_O & (SLAVE == `SLV_PROGRAM_RAM)), .DATA_WE_I(DATA_WE_O), .DATA_SEL_I(DATA_SEL_O), .DATA_ACK_O(PROGRAM_ACK_O) ); wire [31:0] SRAM_DAT_O; WB_SRAM WishboneSRAM ( .CLK_I(CLK_O), .RST_I(RST_O), .ADR_I(DATA_ADR_O[19:2]), .DAT_I(DATA_DAT_O), .DAT_O(SRAM_DAT_O), .STB_I(DATA_STB_O & (SLAVE == `SLV_SRAM)), .WE_I(DATA_WE_O), .SEL_I(DATA_SEL_O), .ACK_O(SRAM_ACK_O), .SRAM_ADR(SRAM_ADR), .SRAM_WE(SRAM_WE), .SRAM_OE(SRAM_OE), .SRAM_IO1(SRAM_IO1), .SRAM_CE1(SRAM_CE1), .SRAM_UB1(SRAM_UB1), .SRAM_LB1(SRAM_LB1), .SRAM_IO2(SRAM_IO2), .SRAM_CE2(SRAM_CE2), .SRAM_UB2(SRAM_UB2), .SRAM_LB2(SRAM_LB2) ); wire [31:0] RS232_DAT_O; RS232 #( .CLOCK_DIV(434) // 115200 bps @ 50 MHz CLKIN ) SerialInterface ( .CLK_I(CLK_O), .RST_I(RST_O), .DAT_I(DATA_DAT_O), .DAT_O(RS232_DAT_O), .STB_I(DATA_STB_O & (SLAVE == `SLV_RS232)), .WE_I(DATA_WE_O), .SEL_I(DATA_SEL_O), .ACK_O(RS232_ACK_O), .TX_FULL(RS232_TX_FULL), .RX_EMPTY(RS232_RX_EMPTY), .RX(RX_A), .TX(TX_A) ); reg [7:0] SWITCH_R; reg [3:0] BTN_R; reg [7:0] LED = 8'h00; reg [19:0] DISPLAY = 20'h00000; SevenSeg Display ( .CLKIN(CLK_O), .INPUT(DISPLAY[15:0]), //.INPUT(INST_ADR_O[15:0]), //.INPUT(DATA_ADR_O[17:2]), .DP(DISPLAY[19:16]), .SEG(SEG), .ANODE(ANODE) ); always @* begin case (SLAVE) `SLV_PROGRAM_RAM: DATA_DAT_I <= PROGRAM_DAT_O; `SLV_SRAM: DATA_DAT_I <= SRAM_DAT_O; `SLV_IRQ_CTL: DATA_DAT_I <= IRQ_DAT_O; `SLV_DMA_CTL: DATA_DAT_I <= DMA_CTL_DAT_O; `SLV_TIMER: DATA_DAT_I <= TIMER_DAT_O; `SLV_LED_SWITCH: DATA_DAT_I <= { 24'h0, SWITCH_R }; `SLV_BTN_DISPLAY: DATA_DAT_I <= { 4'h0, BTN_R, 4'h0, DISPLAY }; `SLV_RS232: DATA_DAT_I <= RS232_DAT_O; default: DATA_DAT_I <= 32'hA5A5A5A5; endcase case (SLAVE) `SLV_PROGRAM_RAM: DATA_ACK_I <= PROGRAM_ACK_O; `SLV_SRAM: DATA_ACK_I <= SRAM_ACK_O; `SLV_IRQ_CTL: DATA_ACK_I <= IRQ_ACK_O; `SLV_DMA_CTL: DATA_ACK_I <= DMA_CTL_ACK_O; `SLV_TIMER: DATA_ACK_I <= TIMER_ACK_O; `SLV_RS232: DATA_ACK_I <= RS232_ACK_O; default: DATA_ACK_I <= DATA_STB_O; endcase end reg [15:0] RST_CNT = 16'hFFFF; always @(posedge CLK_O) begin if (BTN_R[3] & ~&RST_CNT) RST_CNT <= RST_CNT + 16'd1; else if (|RST_CNT) RST_CNT <= RST_CNT - 16'd1; if (RST_CNT == 16'hFFFF) RST_O <= 1'b1; else if (RST_CNT == 16'h0000) RST_O <= 1'b0; end always @(posedge CLK_O) begin BTN_R <= BTN; SWITCH_R <= SWITCH; if (DATA_STB_O & DATA_WE_O) begin case (SLAVE) `SLV_LED_SWITCH: LED <= DATA_DAT_O[7:0]; `SLV_BTN_DISPLAY: begin if (DATA_SEL_O[2]) DISPLAY[19:16] <= DATA_DAT_O[19:16]; if (DATA_SEL_O[1]) DISPLAY[15: 8] <= DATA_DAT_O[15: 8]; if (DATA_SEL_O[0]) DISPLAY[ 7: 0] <= DATA_DAT_O[ 7: 0]; end endcase end end endmodule