
テキストからモールス符号への変換をしているだけです。ソースコードは最適ではありませんが、動作はします。
//===========================================================
// FPGA CW Keyer (MAX10 10M08SAE144C8GES)
//===========================================================
`define POW_ON_RESET_MAX 16'hffff
module FPGA
(
input wire CLK48, // pin 27, 48MHz Clock
output wire[2:0] LED, // pin [122:120], LED Output [Green, Blue, Red]
output wire KEY_OUT // pin 132, CN2-5, key output
);
//--------------------------
// Internal Power on Reset
//--------------------------
wire reset_n ; // Internal Reset Signal
reg pow_on_reset_n ; // power-up level = Low
reg [15:0] pow_on_reset_count ; // power-up level = Low
always @(posedge CLK48)
begin
if (pow_on_reset_count != `POW_ON_RESET_MAX)
begin
pow_on_reset_n <= 1'b0;
pow_on_reset_count <= pow_on_reset_count + 16'h0001;
end
else
begin
pow_on_reset_n <= 1'b1;
pow_on_reset_count <= pow_on_reset_count;
end
end
assign reset_n = pow_on_reset_n;
//--------- counter for dot clock ---------------------
parameter COUNT_PERIOD = 32'h0010_0000;
reg [31:0] count;
wire count_up /* synthesis keep */;
always @ (posedge CLK48 or negedge reset_n)
begin
if ( reset_n == 1'b0 )
begin
count <= 32'h0000_0000;
end
else
begin
if ( count == (COUNT_PERIOD - 32'h0000_0001) )
begin
count <= 32'h0000_0000;
end
else
begin
count <= count + 32'h0000_0001;
end
end
end
assign count_up = ( count == (COUNT_PERIOD - 1) )? 1'b1 : 1'b0;
//--------- 10-bit morse code table (7-bit data and 3-bit length)
parameter N_CODE = 32;
reg [4:0] morse_code;
reg [9:0] code_pattern;
always @(morse_code)
begin
case (morse_code)
5'b0_0000: code_pattern <= 10'b01_00000_010; // a
5'b0_0001: code_pattern <= 10'b1000_000_100; // b
5'b0_0010: code_pattern <= 10'b1010_000_100; // c
5'b0_0011: code_pattern <= 10'b100_0000_011; // d
5'b0_0100: code_pattern <= 10'b0_000000_001; // e
5'b0_0101: code_pattern <= 10'b0010_000_100; // f
5'b0_0110: code_pattern <= 10'b110_0000_011; // g
5'b0_0111: code_pattern <= 10'b0000_000_100; // h
5'b0_1000: code_pattern <= 10'b00_00000_010; // i
5'b0_1001: code_pattern <= 10'b0111_000_100; // j
5'b0_1010: code_pattern <= 10'b101_0000_011; // k
5'b0_1011: code_pattern <= 10'b0100_000_100; // l
5'b0_1100: code_pattern <= 10'b11_00000_010; // m
5'b0_1101: code_pattern <= 10'b10_00000_010; // n
5'b0_1110: code_pattern <= 10'b111_0000_011; // o
5'b0_1111: code_pattern <= 10'b0110_000_100; // p
5'b1_0000: code_pattern <= 10'b1101_000_100; // q
5'b1_0001: code_pattern <= 10'b010_0000_011; // r
5'b1_0010: code_pattern <= 10'b000_0000_011; // s
5'b1_0011: code_pattern <= 10'b1_000000_001; // t
5'b1_0100: code_pattern <= 10'b001_0000_011; // u
5'b1_0101: code_pattern <= 10'b0001_000_100; // v
5'b1_0110: code_pattern <= 10'b011_0000_011; // w
5'b1_0111: code_pattern <= 10'b1001_000_100; // x
5'b1_1000: code_pattern <= 10'b1011_000_100; // y
5'b1_1001: code_pattern <= 10'b1100_000_100; // z
5'b1_1010: code_pattern <= 10'b00000_00_101; // 0
5'b1_1011: code_pattern <= 10'b01111_00_101; // 1
5'b1_1100: code_pattern <= 10'b00111_00_101; // 2
5'b1_1101: code_pattern <= 10'b00011_00_101; // 3
5'b1_1110: code_pattern <= 10'b00001_00_101; // 4
5'b1_1111: code_pattern <= 10'b1000101__111; // <BK>
default : code_pattern <= 10'b00_00000_000; // default
endcase
end
//--------- morse code state transition and output ------------
reg [3:0] r_state;
reg key_out;
reg [6:0] shift_reg;
reg [2:0] length;
always @ (r_state)
begin
case(r_state)
4'b0000: begin key_out <= 1'b0; end // idle
4'b0001: begin key_out <= 1'b1; end // dash 1
4'b0010: begin key_out <= 1'b1; end // dash 2
4'b0011: begin key_out <= 1'b1; end // dash 3
4'b0100: begin key_out <= 1'b0; end // char space 1
4'b0101: begin key_out <= 1'b1; end // dot 1
4'b0110: begin key_out <= 1'b0; end // word space 1
4'b0111: begin key_out <= 1'b0; end // word space 2
4'b1000: begin key_out <= 1'b0; end
4'b1001: begin key_out <= 1'b0; end
4'b1010: begin key_out <= 1'b0; end
4'b1011: begin key_out <= 1'b0; end
4'b1100: begin key_out <= 1'b0; end
4'b1101: begin key_out <= 1'b0; end
4'b1110: begin key_out <= 1'b0; end
4'b1111: begin key_out <= 1'b0; end
endcase
end
assign KEY_OUT = key_out;
always @ (posedge CLK48 or negedge reset_n)
begin
if ( reset_n == 1'b0 )
begin
r_state <= 4'b0000;
morse_code <= 5'b0_0000;
end
else
begin
if(count_up)
begin
case (r_state)
4'b0000:
begin
r_state <= 4'b0001;
end
4'b0001:
begin
r_state <= 4'b0010;
end
4'b0010:
begin
r_state <= 4'b0011;
end
4'b0011:
begin
r_state <= 4'b0100;
end
4'b0100:
if(length != 3'b000)
begin
if(shift_reg[5]) // not MSB because before shift
begin
r_state <= 4'b0001;
end
else
begin
r_state <= 4'b0101;
end
shift_reg <= {shift_reg[5:0], 1'b0};
length <= length - 3'b001;
end
else
begin
r_state <= 4'b0110;
end
4'b0101:
begin
r_state <= 4'b0100;
end
4'b0110:
begin
shift_reg <= code_pattern[9:3];
length <= code_pattern[2:0] - 3'b001;
if(morse_code == (N_CODE - 1) )
begin
morse_code <= 5'b0_0000;
end
else
begin
morse_code <= morse_code + 5'b0_0001;
end
r_state <= 4'b0111;
end
4'b0111:
begin
if(shift_reg[6])
begin
r_state <= 4'b0001;
end
else
begin
r_state <= 4'b0101;
end
end
default:
begin
r_state <= r_state;
end
endcase
end
else
begin
r_state <= r_state;
end
end
end
//----------------
// LED Output
//----------------
reg [2:0] myled ;
always @(posedge CLK48, negedge reset_n)
begin
if (reset_n == 1'b0 )
begin
myled <= 3'b001;
end
else
begin
myled <= r_state[2:0];
end
end
assign LED = ~myled;
//===========================================================
endmodule
//===========================================================