stack-machine/toplevel.v

422 lines
10 KiB
Verilog

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_DCM), // 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
);
BUFG BUFB0 (
.I(CLK0_DCM),
.O(CLK0)
);
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