訊息
|
CPU0 16 位元版
module computer0m(input clock, reset, output [2:0] tick,
output [15:0] ir, pc, mar, mdr,
inout [15:0] dbus, output m_en, m_rw);
cpu0m cpu (.clock(clock), .reset(reset), .pc(pc), .tick(tick), .ir(ir),
.mar(mar), .mdr(mdr), .dbus(dbus), .m_en(m_en), .m_rw(m_rw));
memory0m mem (.clock(clock), .reset(reset), .en(m_en), .rw(m_rw),
.abus(mar), .dbus_in(mdr), .dbus_out(dbus));
endmodule
module cpu0m(input clock, reset, output reg [2:0] tick,
output reg [15:0] ir, pc, mar, mdr,
inout [15:0] dbus, output reg m_en, m_rw);
reg signed [15:0] R [0:15];
reg [4:0] op;
reg [10:0] ra, rb;
reg signed [10:0] cx11;
reg signed [15:0] addr16, A, B, ipc; // ipc:instruction PC
`define PC R[15]
`define SW R[12] // 狀態暫存器
`define N `SW[15] // 負號旗標
`define Z `SW[14] // 零旗標
`define LD 5'b00000 `define ST 5'b00001 `define CMP 5'b00010 `define MOV 5'b00011
`define ADD 5'b00100 `define SUB 5'b00101 `define MUL 5'b00110 `define DIV 5'b00111
`define AND 5'b01000 `define OR 5'b01001 `define XOR 5'b01010 `define JEQ 5'b01011
`define JNE 5'b01100 `define JLT 5'b01101 `define JGT 5'b01110 `define JMP 5'b01111
always @(posedge clock) begin
if (reset) begin
`PC = 0;
`SW = 0;
tick = 0;
end
else begin
tick = tick+1;
m_en = 0;
case (tick)
// 指令擷取階段 Tick 1..3 : memory.read(m[PC])
1: begin // Tick 1:將 PC 丟到位址匯流排上
mar = `PC; // MAR = PC
m_rw = 1; // m_rw=1 is read mode, read(m[MAR]) => read(m[PC])
m_en = 1;
ipc = `PC;
`PC = `PC+2; // PC = PC+2
end
2: begin // Tick 2:ir = m[PC]
mdr = dbus;
ir = mdr; // IR = dbus = m[PC]
{op,rb} = ir;
cx11 = ir[10:0];
end
3: begin // Tick 3:取出暫存器 R[ra], R[rb] 內容
m_en = 0;
A = R[ra];
B = R[rb];
end
// 指令執行階段 Tick 4..6 : execute(IR)
4: begin
case (op) // 解讀 OP: Tick 4
`LD: begin // 指令:LD cx ; 語意:R[ra] = m[rb+cx]
mar =cx11; // mar = 讀取位址 = R[rb]+cx
m_rw = 1; // 讀取模式:read
m_en = 1;
end
`ST: begin // 指令:ST cx ; 語意:m[rb+cx]=R[ra]
mar = cx11; // 寫入位址 = R[rb]+cx
mdr = R[2]; // 寫入資料:R[ra]
m_rw = 0; // 寫入模式:write
m_en = 1;
end
`CMP: begin // 指令:JMP cx ; 語意:PC = PC+cx
`N=(R[1]-B<0);
`Z=(R[1]-B==0);
end
`MOV: begin // 指令:MOV ra, rb ; 語意:R[ra]=R[rb]
R[1] = B;
end
`ADD: begin // 指令:ADD ra, ra, rb ; 語意:R[ra]=R[ra]+R[rb] ADD cx => R1 = R1 + [cx]
R[1] = R[1]+B; // 執行加法
end
`SUB: begin // 指令:SUB ra, ra, rb ; 語意:R[ra]=R[ra]-R[rb]
R[1] = R[1]-B; // 執行減法
end
// `MUL: begin // 指令:MUL ra, ra, rb ; 語意:R[ra]=R[ra]*R[rb]
// R[1] = R[1]*B; // 執行乘法
// end
// `DIV: begin // 指令:DIV ra, ra, rb ; 語意:R[ra]=R[ra]/R[rb]
// R[1] = R[1]/B; // 執行除法
// end
`AND: begin // 指令:AND ra, ra, rb ; 語意:R[ra]=R[ra]&R[rb]
R[1] = R[1]&B; // 執行AND
end
`OR: begin // 指令:OR ra, ra, rb ; 語意:R[ra]=R[ra]|R[rb]
R[1] = R[1]|B; // 執行OR
end
`XOR: begin // 指令:XOR ra, ra, rb ; 語意:R[ra]=R[ra]^R[rb]
R[1] = R[1]^B; // 執行XOR
end
`JEQ: begin // 指令:JMP cx ; 語意:PC = PC+cx
if (`Z) `PC=`PC+cx11;
end
`JNE: begin // 指令:JNE Cx; 語意:if SW(!=) PC=PC+Cx
if (!`Z) `PC=`PC+cx11; // 跳躍 (不相等)
end
`JLT: begin // 指令:JLT Cx; 語意:if SW(<) PC=PC+Cx
if (`N) `PC=`PC+cx11; // 跳躍 ( < )
end
`JGT: begin // 指令:JGT Cx; 語意:if SW(>) PC=PC+Cx
if (!`N && !`Z) `PC=`PC+cx11; // 跳躍 ( > )
end
`JMP: begin // 指令:JMP cx ; 語意:PC = PC+cx
addr16 = cx11; // 取出 cx 並轉為 32 位元有號數
`PC = `PC+addr16; // 跳躍目標位址=PC+cx
end
default: begin
end
endcase
end
5: begin // 解讀 OP: Tick 5
case (op) // LD ra, rb, cx ; R[ra] = R[rb+cx] ; mdr = R[rb+cx]
`LD: begin // 指令:LD ra, rb, cx ; 語意:R[ra] = m[rb+cx]
mdr = dbus; // 取得記憶體傳回的 dbus = m[rb+cx]
R[2] = mdr; // 存入到目標暫存器 R[ra] 中
R[1]=0;
m_en = 0; // 讀取完畢
end
`ST: begin // 指令:ST ra, rb, cx ; 語意:m[rb+cx]=R[ra]
m_en = 0; // 寫入完畢
end
default: begin
end
endcase
end
6: begin
case (op) // 解讀 OP: Tick 6; 列印
`LD: $display("%4dns %8x : LD 2,%7x; R[2]=%4d",
$stime, ipc, cx11, R[2]);
`ST: $display("%4dns %8x : ST 2,%7x; R[2]=%4d",
$stime, ipc, cx11, R[2]);
`CMP:$display("%4dns %8x : CMP 2, 1,%4x; R[1]=%4d",
$stime, ipc, rb, R[1]);
`MOV:$display("%4dns %8x : MOV 1, 2,%4x; R[1]=%4d",
$stime, ipc, rb, R[1]);
`ADD:$display("%4dns %8x : ADD 1, 1,%4x; R[1]=%4d, B=%4d",
$stime, ipc, rb, R[1], B);
`SUB:$display("%4dns %8x : SUB 1, 1,%4x; R[1]=%4d, B=%4d",
$stime, ipc, rb, R[1], B);
`MUL:$display("%4dns %8x : MUL 1, 1,%4x; R[1]=%4d, B=%4d",
$stime, ipc, rb, R[1], B);
`DIV:$display("%4dns %8x : DIV 1, 1,%4x; R[1]=%4d, B=%4d",
$stime, ipc, rb, R[1], B);
`AND:$display("%4dns %8x : AND 1, 1,%4x; R[1]=%4d, B=%4d",
$stime, ipc, rb, R[1], B);
`OR: $display("%4dns %8x : OR 1, 1,%4x; R[1]=%4d, B=%4d",
$stime, ipc, rb, R[1], B);
`XOR:$display("%4dns %8x : XOR 1, 1,%4x; R[1]=%4d, B=%4d",
$stime, ipc, rb, R[1], B);
`JEQ:$display("%4dns %8x : JEQ %10d; PC=%8x",
$stime, ipc, cx11, R[15]);
`JNE:$display("%4dns %8x : JNE %10d; PC=%8x",
$stime, ipc, cx11, R[15]);
`JLT:$display("%4dns %8x : JLT %10d; PC=%8x",
$stime, ipc, cx11, R[15]);
`JGT:$display("%4dns %8x : JGT %10d; PC=%8x",
$stime, ipc, cx11, R[15]);
`JMP:$display("%4dns %8x : JMP %10d; PC=%8x",
$stime, ipc, cx11, R[15]);
endcase
tick = 0;
end
default: begin
end
endcase
end
pc = `PC;
end
endmodule
module memory0m(input clock, reset, en, rw,
input [15:0] abus, dbus_in, output [15:0] dbus_out,
// 陳鍾誠加
output [7:0] lcd_char, input [7:0] scan_code);
reg [7:0] m [0:128];
reg [15:0] data;
always @(clock or reset or abus or en or rw or dbus_in)
begin
if (reset == 1) begin
{m[0],m[1]} = 16'b0000000000000110; // 0000 LD R1, K1
{m[2],m[3]} = 16'b0000000000001000; // 0002 LD R2, K2
{m[4],m[5]} = 16'b0111100000000100; // 0004 JMP 4
{m[6],m[7]} = 16'b0000000000000001; // 0006 K1: WORD 1
{m[8],m[9]} = 16'b0000000000000010; // 0008 K2: WORD 2
{m[10],m[11]}= 16'b0010000000000010; // 000A F1: ADD R1, R1, R2
{m[12],m[13]}= 16'b0010100000000010; // 000C SUB R1, R1, R2
{m[14],m[15]}= 16'b0011000000000010; // 000E MUL R1, R1, R2
{m[16],m[17]}= 16'b0011100000000010; // 0010 DIV R1, R1, R2
{m[18],m[19]}= 16'b0000100000010000; // 0012 ST R2, K0
{m[20],m[21]}= 16'b0111100000000010; // 0014 JMP 2
// 陳鍾誠加
{m[20],m[21]}= 16'b0111100000000010; // 0014 LD [65531] // R1 = 鍵盤按鍵
{m[20],m[21]}= 16'b0111100000000010; // 0014 ST [65530] // 螢幕顯示 R1=鍵盤按鍵
{m[20],m[21]}= 16'b0111100000000010; // 0014 LD CH
{m[20],m[21]}= 16'b0111100000000010; // 0014 ST [65530] // 螢幕顯示 'A'
{m[22],m[23]}= 16'b0000000000000100; // 0016 K0: WORD 4
{m[22],m[23]}= 16'b0000000000000100; // 0016 CH: BYTE 'A'
{m[24],m[25]}= 16'b0000000000010000; // 0018 LD R1, K0
{m[26],m[27]}= 16'b0001100000000010; // 001A MOV R1, R2
{m[28],m[29]}= 16'b0010000000000010; // 001C ADD R1, R1, R2
{m[30],m[31]}= 16'b0001000000000010; // 001E CMP R2, R1
{m[32],m[33]}= 16'b0111011111101000; // 0020 JGT F1
data = 16'hZZZZ;
end else if (abus >=0 && abus < 125) begin
if (en == 1 && rw == 0) begin // r_w==0:write
data = dbus_in;
{m[abus], m[abus+1]} = dbus_in;
end
else if (en == 1 && rw == 1) // r_w==1:read
data = {m[abus], m[abus+1]};
else
data = 16'hZZZZ;
end else
data = 16'hZZZZ;
end
assign dbus_out = data;
assign lcd_char = m[65530];
assign m[65531] = scan_code;
endmodule
module main;
reg clock;
reg reset;
wire [2:0] tick;
wire [15:0] pc, ir, mar, mdr, dbus;
wire m_en, m_rw;
wire [4:0] op;
wire signed [15:0] A, B;
wire [10:0] ra, rb;
computer0m DUT (.clock(clock), .reset(reset), .pc(pc), .tick(tick),
.ir(ir), .mar(mar), .mdr(mdr), .dbus(dbus), .m_en(m_en), .m_rw(m_rw));
initial
begin
clock = 0;
reset = 1;
end
initial #20 reset = 0;
always #10 clock=clock+1;
initial #2000 $finish;
endmodule
周邊
module lcdlab3(
input CLOCK_50, // 50 MHz clock
//LCD Module 16X2
output LCD_ON, // LCD Power ON/OFF
output LCD_BLON, // LCD Back Light ON/OFF
output LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read
output LCD_EN, // LCD Enable
output LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data
inout [7:0] LCD_DATA, // LCD Data bus 8 bits
// PS2 data and clock lines
input PS2_DAT,
input PS2_CLK
);
// reset delay gives some time for peripherals to initialize
wire DLY_RST;
Reset_Delay r0( .iCLK(CLOCK_50),.oRESET(DLY_RST) );
// turn LCD ON
assign LCD_ON = 1'b1;
assign LCD_BLON = 1'b1;
wire reset = 1'b0;
wire [7:0] scan_code;
wire read, scan_ready;
oneshot pulser(
.pulse_out(read),
.trigger_in(scan_ready),
.clk(CLOCK_50)
);
keyboard kbd(
.keyboard_clk(PS2_CLK),
.keyboard_data(PS2_DAT),
.clock50(CLOCK_50),
.reset(reset),
.read(read),
.scan_ready(scan_ready),
.scan_code(scan_code)
);
LCD_Display u1(
// Host Side
.iCLK_50MHZ(CLOCK_50),
.iRST_N(DLY_RST),
.hex0(lcd_char), //Display Scan_Code
// LCD Side
.DATA_BUS(LCD_DATA),
.LCD_RW(LCD_RW),
.LCD_E(LCD_EN),
.LCD_RS(LCD_RS)
);
endmodule
module oneshot(output reg pulse_out, input trigger_in, input clk);
reg delay;
always @ (posedge clk)
begin
if (trigger_in && !delay) pulse_out <= 1'b1;
else pulse_out <= 1'b0;
delay <= trigger_in;
end
endmodule
module Reset_Delay(iCLK,oRESET);
input iCLK;
output reg oRESET;
reg [19:0] Cont;
always@(posedge iCLK)
begin
if(Cont!=20'hFFFFF)
begin
Cont <= Cont+1'b1;
oRESET <= 1'b0;
end
else
oRESET <= 1'b1;
end
endmodule
module keyboard(keyboard_clk, keyboard_data, clock50, reset, read, scan_ready, scan_code);
input keyboard_clk;
input keyboard_data;
input clock50; // 50 Mhz system clock
input reset;
input read;
output scan_ready;
output [7:0] scan_code;
reg ready_set;
reg [7:0] scan_code;
reg scan_ready;
reg read_char;
reg clock; // 25 Mhz internal clock
reg [3:0] incnt;
reg [8:0] shiftin;
reg [7:0] filter;
reg keyboard_clk_filtered;
// scan_ready is set to 1 when scan_code is available.
// user should set read to 1 and then to 0 to clear scan_ready
always @ (posedge ready_set or posedge read)
if (read == 1) scan_ready <= 0;
else scan_ready <= 1;
// divide-by-two 50MHz to 25MHz
always @(posedge clock50)
clock <= ~clock;
// This process filters the raw clock signal coming from the keyboard
// using an eight-bit shift register and two AND gates
always @(posedge clock)
begin
filter <= {keyboard_clk, filter[7:1]};
if (filter==8'b1111_1111) keyboard_clk_filtered <= 1;
else if (filter==8'b0000_0000) keyboard_clk_filtered <= 0;
end
// This process reads in serial data coming from the terminal
always @(posedge keyboard_clk_filtered)
begin
if (reset==1)
begin
incnt <= 4'b0000;
read_char <= 0;
end
else if (keyboard_data==0 && read_char==0)
begin
read_char <= 1;
ready_set <= 0;
end
else
begin
// shift in next 8 data bits to assemble a scan code
if (read_char == 1)
begin
if (incnt < 9)
begin
incnt <= incnt + 1'b1;
shiftin = { keyboard_data, shiftin[8:1]};
ready_set <= 0;
end
else
begin
incnt <= 0;
scan_code <= shiftin[7:0];
read_char <= 0;
ready_set <= 1;
end
end
end
end
endmodule
/*
ENTITY LCD_Display IS
-- Enter number of live Hex hardware data values to display
-- (do not count ASCII character constants)
GENERIC(Num_Hex_Digits: Integer:= 2);
-----------------------------------------------------------------------
-- LCD Displays 16 Characters on 2 lines
-------------------------------------------------------------------
-- ASCII HEX TABLE
-- Hex Low Hex Digit
-- Value 0 1 2 3 4 5 6 7 8 9 A B C D E F
------\----------------------------------------------------------------
--H 2 | SP ! " # $ % & ' ( ) * + , - . /
--i 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
--g 4 | @ A B C D E F G H I J K L M N O
--h 5 | P Q R S T U V W X Y Z [ \ ] ^ _
-- 6 | ` a b c d e f g h i j k l m n o
-- 7 | p q r s t u v w x y z { | } ~ DEL
-----------------------------------------------------------------------
*/
module LCD_Display(iCLK_50MHZ, iRST_N, hex0,
LCD_RS,LCD_E,LCD_RW,DATA_BUS);
input iCLK_50MHZ, iRST_N;
input [7:0] hex0;
output LCD_RS, LCD_E, LCD_RW;
inout [7:0] DATA_BUS;
parameter
HOLD = 4'h0,
FUNC_SET = 4'h1,
DISPLAY_ON = 4'h2,
MODE_SET = 4'h3,
Print_String = 4'h4,
LINE2 = 4'h5,
RETURN_HOME = 4'h6,
DROP_LCD_E = 4'h7,
RESET1 = 4'h8,
RESET2 = 4'h9,
RESET3 = 4'ha,
DISPLAY_OFF = 4'hb,
DISPLAY_CLEAR = 4'hc;
reg [3:0] state, next_command;
// Enter new ASCII hex data above for LCD Display
reg [7:0] DATA_BUS_VALUE;
wire [7:0] Next_Char;
reg [19:0] CLK_COUNT_400HZ;
reg [4:0] CHAR_COUNT;
reg CLK_400HZ, LCD_RW_INT, LCD_E, LCD_RS;
// BIDIRECTIONAL TRI STATE LCD DATA BUS
assign DATA_BUS = (LCD_RW_INT? 8'bZZZZZZZZ: DATA_BUS_VALUE);
LCD_display_string u1(
.index(CHAR_COUNT),
.out(Next_Char),
.hex0(hex0));
assign LCD_RW = LCD_RW_INT;
always @(posedge iCLK_50MHZ or negedge iRST_N)
if (!iRST_N)
begin
CLK_COUNT_400HZ <= 20'h00000;
CLK_400HZ <= 1'b0;
end
else if (CLK_COUNT_400HZ < 20'h0F424)
begin
CLK_COUNT_400HZ <= CLK_COUNT_400HZ + 1'b1;
end
else
begin
CLK_COUNT_400HZ <= 20'h00000;
CLK_400HZ <= ~CLK_400HZ;
end
// State Machine to send commands and data to LCD DISPLAY
always @(posedge CLK_400HZ or negedge iRST_N)
if (!iRST_N)
begin
state <= RESET1;
end
else
case (state)
RESET1:
// Set Function to 8-bit transfer and 2 line display with 5x8 Font size
// see Hitachi HD44780 family data sheet for LCD command and timing details
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h38;
state <= DROP_LCD_E;
next_command <= RESET2;
CHAR_COUNT <= 5'b00000;
end
RESET2:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h38;
state <= DROP_LCD_E;
next_command <= RESET3;
end
RESET3:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h38;
state <= DROP_LCD_E;
next_command <= FUNC_SET;
end
// EXTRA STATES ABOVE ARE NEEDED FOR RELIABLE PUSHBUTTON RESET OF LCD
FUNC_SET:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h38;
state <= DROP_LCD_E;
next_command <= DISPLAY_OFF;
end
// Turn off Display and Turn off cursor
DISPLAY_OFF:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h08;
state <= DROP_LCD_E;
next_command <= DISPLAY_CLEAR;
end
// Clear Display and Turn off cursor
DISPLAY_CLEAR:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h01;
state <= DROP_LCD_E;
next_command <= DISPLAY_ON;
end
// Turn on Display and Turn off cursor
DISPLAY_ON:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h0C;
state <= DROP_LCD_E;
next_command <= MODE_SET;
end
// Set write mode to auto increment address and move cursor to the right
MODE_SET:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h06;
state <= DROP_LCD_E;
next_command <= Print_String;
end
// Write ASCII hex character in first LCD character location
Print_String:
begin
state <= DROP_LCD_E;
LCD_E <= 1'b1;
LCD_RS <= 1'b1;
LCD_RW_INT <= 1'b0;
// ASCII character to output
if (Next_Char[7:4] != 4'h0)
DATA_BUS_VALUE <= Next_Char;
// Convert 4-bit value to an ASCII hex digit
else if (Next_Char[3:0] >9)
// ASCII A...F
DATA_BUS_VALUE <= {4'h4,Next_Char[3:0]-4'h9};
else
// ASCII 0...9
DATA_BUS_VALUE <= {4'h3,Next_Char[3:0]};
// Loop to send out 32 characters to LCD Display (16 by 2 lines)
if ((CHAR_COUNT < 31) && (Next_Char != 8'hFE))
CHAR_COUNT <= CHAR_COUNT + 1'b1;
else
CHAR_COUNT <= 5'b00000;
// Jump to second line?
if (CHAR_COUNT == 15)
next_command <= LINE2;
// Return to first line?
else if ((CHAR_COUNT == 31) || (Next_Char == 8'hFE))
next_command <= RETURN_HOME;
else
next_command <= Print_String;
end
// Set write address to line 2 character 1
LINE2:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'hC0;
state <= DROP_LCD_E;
next_command <= Print_String;
end
// Return write address to first character postion on line 1
RETURN_HOME:
begin
LCD_E <= 1'b1;
LCD_RS <= 1'b0;
LCD_RW_INT <= 1'b0;
DATA_BUS_VALUE <= 8'h80;
state <= DROP_LCD_E;
next_command <= Print_String;
end
// The next three states occur at the end of each command or data transfer to the LCD
// Drop LCD E line - falling edge loads inst/data to LCD controller
DROP_LCD_E:
begin
LCD_E <= 1'b0;
state <= HOLD;
end
// Hold LCD inst/data valid after falling edge of E line
HOLD:
begin
state <= next_command;
end
endcase
endmodule
module LCD_display_string(index,out,hex0);
input [4:0] index;
input [7:0] hex0;
output [7:0] out;
reg [7:0] out;
// ASCII hex values for LCD Display
// Enter Live Hex Data Values from hardware here
// LCD DISPLAYS THE FOLLOWING:
//----------------------------
//| Count=XX |
//| DE2 |
//----------------------------
// Line 1
always
case (index)
5'h00: out <= 8'h50; //P
5'h01: out <= 8'h53; //S
5'h02: out <= 8'h32; //2
5'h03: out <= 8'h20; //
5'h04: out <= 8'h53; //S
5'h05: out <= 8'h63; //c
5'h06: out <= 8'h61; //a
5'h07: out <= 8'h6e; //n
5'h08: out <= 8'h43; //C
5'h09: out <= 8'h6f; //o
5'h0a: out <= 8'h64; //d
5'h0b: out <= 8'h65; //e
5'h0c: out <= 8'h3D; //=
5'h0d: out <= ASCII(hex0);
// Line 2
5'h10: out <= 8'h44; //D
5'h11: out <= 8'h45; //E
5'h12: out <= 8'h32; //2
5'h13: out <= 8'h5f; //
5'h14: out <= 8'h37; //7
5'h15: out <= 8'h30; //0
5'h16: out <= 8'h20; //
5'h17: out <= 8'h50; //P
5'h18: out <= 8'h53; //S
5'h19: out <= 8'h32; //2
5'h1a: out <= 8'h2b; //+
5'h1b: out <= 8'h4c; //L
5'h1c: out <= 8'h43; //C
5'h1d: out <= 8'h44; //D
default: out <= 8'h20;
endcase
function [7:0] ASCII;
input [7:0] data;
case(data)
/*A-Z*/
8'h1c:ASCII=8'h41;
8'h32:ASCII=8'h42;
8'h21:ASCII=8'h43;
8'h23:ASCII=8'h44;
8'h24:ASCII=8'h45;
8'h2B:ASCII=8'h46;
8'h34:ASCII=8'h47;
8'h33:ASCII=8'h48;
8'h43:ASCII=8'h49;
8'h3B:ASCII=8'h4A;
8'h42:ASCII=8'h4B;
8'h4B:ASCII=8'h4C;
8'h3A:ASCII=8'h4D;
8'h31:ASCII=8'h4E;
8'h44:ASCII=8'h4F;
8'h4D:ASCII=8'h50;
8'h15:ASCII=8'h51;
8'h2D:ASCII=8'h52;
8'h1B:ASCII=8'h53;
8'h2C:ASCII=8'h54;
8'h3C:ASCII=8'h55;
8'h2A:ASCII=8'h56;
8'h1D:ASCII=8'h57;
8'h22:ASCII=8'h58;
8'h35:ASCII=8'h59;
8'h1A:ASCII=8'h5A;
/*0-9 top*/
8'h45:ASCII=8'h30;
8'h16:ASCII=8'h31;
8'h1E:ASCII=8'h32;
8'h26:ASCII=8'h33;
8'h25:ASCII=8'h34;
8'h2E:ASCII=8'h35;
8'h36:ASCII=8'h36;
8'h3D:ASCII=8'h37;
8'h3E:ASCII=8'h38;
8'h46:ASCII=8'h39;
/*0-9 right*/
8'h70:ASCII=8'h30;
8'h69:ASCII=8'h31;
8'h72:ASCII=8'h32;
8'h7A:ASCII=8'h33;
8'h6B:ASCII=8'h34;
8'h73:ASCII=8'h35;
8'h74:ASCII=8'h36;
8'h6C:ASCII=8'h37;
8'h75:ASCII=8'h38;
8'h7D:ASCII=8'h39;
default:begin
ASCII=8'h00;
end
endcase
endfunction
endmodule
參考文獻
- LAB09 PS2 Scan Code 送至 LCD1602 適用於DE2-70
Facebook
|
Post preview:
Close preview