?? s3esk_startup.v
字號:
`timescale 1ns / 1ps// Lab design for the Designing for Performance ChipScope lab.
// This design is based on a reference design for the Spartan-3E Starter Kit.
//
// Constantly scroll the text ?SPARTAN-3E STARTER KIT" and "www.xilinx.com/s3estarter? across the LCD.
//
// SW0 turns on LD0
// SW1 turns on LD1 Single LED is moved left or
// SW2 turns on LD2 right by rotation of control.
// SW3 turns on LD3 OR
// BTN East turns on LD4 by pressing centre
// BTN South turns on LD5 button of rotary encoder
// BTN North turns on LD6 toggle mode
// BTN West turns on LD7
//
// PicoBlaze provides full control over the LCD display.
//////////////////////////////////////////////////////////////////////////////////
module s3esk_startup(led, strataflash_oe, strataflash_ce, strataflash_we, switch, btn_north, btn_east, btn_south, btn_west, lcd_d, lcd_rs, lcd_rw, lcd_e, rotary_a, rotary_b, rotary_press, clk); output reg [7:0] led; output strataflash_oe; output strataflash_ce; output strataflash_we; input [3:0] switch; input btn_north; input btn_east; input btn_south; input btn_west; inout [7:4] lcd_d; output reg lcd_rs; output lcd_rw; output reg lcd_e; input rotary_a; input rotary_b; input rotary_press; input clk;//////////////////////////////////////////////////////////////////////////////////// Signals used by ChipScope Pro cores
//
//
// Signals used to connect KCPSM3 to program ROM and I/O logic
//
wire [9:0] address;
wire [17:0] instruction;
wire [7:0] port_id;
wire [7:0] out_port;
reg [7:0] in_port;
wire write_strobe;
wire read_strobe;
reg interrupt;
wire interrupt_ack;
wire kcpsm3_reset;
//
// Signals used to connect program ROM to BSCAN
//
// The BSCAN component would normally be embedded in the control block,
// but it is instantiated at the top level to facilitate replacing it
// with the BSCAN component that will be included in the ICON core.
//
wire capture;
wire drck1;
wire drck2;
wire reset;
wire sel1;
wire sel2;
wire shift;
wire tdi;
wire update;
wire tdo1;
wire tdo2;
//
//
// Signals for LCD operation
//
// Tri-state output requires internal signals
// 'lcd_drive' is used to differentiate between LCD and StrataFLASH communications
// which share the same data bits.
//
reg lcd_rw_control;
reg [7:4] lcd_output_data;
reg lcd_drive;
//
//
// Signals used to interface to rotary encoder
//
reg rotary_a_in;
reg rotary_b_in;
reg rotary_press_in;
reg [1:0] rotary_in;
reg rotary_q1;
reg rotary_q2;
reg delay_rotary_q1;
reg rotary_event;
reg rotary_left;
//////////////////////////////////////////////////////////////////////////////////// Start of circuit description
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Instantiate ChipScope Pro cores here
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Disable unused components
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
//StrataFLASH must be disabled to prevent it conflicting with the LCD display
//
assign strataflash_oe = 1'b1;
assign strataflash_ce = 1'b1;
assign strataflash_we = 1'b1;
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KCPSM3 and the program memory
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
kcpsm3 processor (
.address(address),
.instruction(instruction),
.port_id(port_id),
.write_strobe(write_strobe),
.out_port(out_port),
.read_strobe(read_strobe),
.in_port(in_port),
.interrupt(interrupt),
.interrupt_ack(interrupt_ack),
.reset(kcpsm3_reset),
.clk(clk)
);
control program_rom (
.address(address),
.instruction(instruction),
.proc_reset(kcpsm3_reset), //JTAG Loader version
.clk(clk),
.tdi(tdi),
.update(update),
.sel1(sel1),
.drck1(drck1),
.tdo1(tdo1)
);
BSCAN_SPARTAN3 BSCAN_SPARTAN3_inst ( .CAPTURE(capture), // CAPTURE output from TAP controller .DRCK1(drck1), // Data register output for USER1 functions .DRCK2(drck2), // Data register output for USER2 functions .RESET(reset), // Reset output from TAP controller .SEL1(sel1), // USER1 active output .SEL2(sel2), // USER2 active output .SHIFT(shift), // SHIFT output from TAP controller .TDI(tdi), // TDI output from TAP controller .UPDATE(update), // UPDATE output from TAP controller .TDO1(tdo1), // Data input for USER1 function .TDO2(tdo2) // Data input for USER2 function );
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Interrupt
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Interrupt is used to detect rotation of the rotary encoder.
// It is anticipated that the processor will respond to interrupts at a far higher
// rate that the rotary control can be operated and hence events will not be missed.
//
always @(posedge clk) if (interrupt_ack) begin interrupt <= 0; end else if (rotary_event) begin interrupt <= 1; end
else begin
interrupt <= interrupt;
end
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KCPSM3 input ports
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
//
// The inputs connect via a pipelined multiplexer
//
always @(posedge clk) case (port_id[1:0])
// read simple toggle switches and buttons at address 00 hex 2'b00: in_port = {btn_west, btn_north, btn_south, btn_east, switch};
// read rotary control signals at address 01 hex 2'b01: in_port = {6'b000000, rotary_press_in, rotary_left};
// read LCD data at address 02 hex 2'b10: in_port = {lcd_d, 4'b0000};
// Address 03 hex is unused 2'b11: in_port = 8'b00000000; endcase
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KCPSM3 output ports
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
// adding the output registers to the processor
always @(posedge clk)
if (write_strobe) begin
// Write to LEDs at address 80 hex.
if (port_id[7]) begin
led <= out_port;
end
// LCD data output and controls at address 40 hex.
if (port_id[6]) begin
lcd_output_data <= out_port[7:4];
lcd_drive <= out_port[3];
lcd_rs <= out_port[2];
lcd_rw_control <= out_port[1];
lcd_e <= out_port[0];
end
end
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // LCD interface
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
// The 4-bit data port is bidirectional.
// lcd_rw is '1' for read and '0' for write
// lcd_drive is like a master enable signal which prevents either the
// FPGA outputs or the LCD display driving the data lines.
//
// Control of read and write signal
assign lcd_rw = lcd_rw_control & lcd_drive;
// use read/write control to enable output buffers.
assign lcd_d = (!lcd_rw_control && lcd_drive) ? lcd_output_data : 4'bZZZZ;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Interface to rotary encoder.
// Detection of movement and direction.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
// The rotary switch contacts are filtered using their offset (one-hot) style to
// clean them. Circuit concept by Peter Alfke.
// Note that the clock rate is fast compared with the switch rate.
always @(posedge clk) begin
// Synchronise inputs to clock domain using flip-flops in input/output blocks.
rotary_a_in <= rotary_a; rotary_b_in <= rotary_b; rotary_press_in <= rotary_press;
// Concatinate rotary input signals to form vector for case construct.
rotary_in <= {rotary_b_in, rotary_a_in};
case (rotary_in) 2'b00: begin
rotary_q1 <= 1'b0;
rotary_q2 <= rotary_q2;
end 2'b01: begin
rotary_q1 <= rotary_q1;
rotary_q2 <= 1'b0;
end 2'b10: begin
rotary_q1 <= rotary_q1;
rotary_q2 <= 1'b1;
end 2'b11: begin
rotary_q1 <= 1'b1;
rotary_q2 <= rotary_q2;
end endcase
end
//
// The rising edges of 'rotary_q1' indicate that a rotation has occurred and the
// state of 'rotary_q2' at that time will indicate the direction.
//
always @(posedge clk) begin
delay_rotary_q1 <= rotary_q1;
if (rotary_q1 && !delay_rotary_q1) begin
rotary_event <= 1'b1;
rotary_left <= 1'b1;
end
else begin
rotary_event <= 1'b0;
rotary_left <= rotary_left;
end
end
endmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -