Skip to content

Instantly share code, notes, and snippets.

@geoffrasb
Created June 13, 2012 12:09
Show Gist options
  • Save geoffrasb/2923674 to your computer and use it in GitHub Desktop.
Save geoffrasb/2923674 to your computer and use it in GitHub Desktop.
brainfuck implementation in verilog
module Console_module (
input reset,
output [7:0] LCD_DATA,
output LCD_ENABLE,
output LCD_RW,
output LCD_RSTN,
output LCD_CS1,
output LCD_CS2,
output LCD_DI,
input lcd_clock,
input working_clock,
//abstract interface
input to_mode,
input change_mode,
input please_wait,
//input [13:0]mem_monitor1,
input [13:0]mem_monitor2,
//input [13:0]mem_monitor3,
input [3:0]symbol_to_insert,
input insert,
input delete,
input cursor_dir,
input move_cursor
);
parameter ceo = 4'b1001,
reg output_device = 0;
reg output_device_next = 0;
LCD_display_module lcd(
.lcd_clock(lcd_clock),
.working_clock(working_clock),
.LCD_DATA(LCD_DATA),
.LCD_ENABLE(LCD_ENABLE),
.LCD_RW(LCD_RW),
.LCD_RSTN(LCD_RSTN),
.LCD_CS1(LCD_CS1),
.LCD_CS2(LCD_CS2),
.LCD_DI(LCD_DI),
.to_mode(to_mode),
.change_mode(change_mode),
.please_wait(please_wait),
//.mem_monitor1(mem_monitor1),
.mem_monitor2(mem_monitor2),
//.mem_monitor3(mem_monitor3),
.symbol_to_insert(symbol_to_insert),
.insert(insert),
.delete(delete),
.cursor_dir(cursor_dir),
.move_cursor(move_cursor),
.output_device(output_device)
);
/*
always@(posedge working_clock) begin
output_device <= output_device_next;
end
always@(*) begin
output_device_next = output_device;
if(insert && symbol_to_insert == ceo)
output_device_next = output_device+1;
else if(delete && mem_monitor1[7:0]==ceo)
output_device_next = output_device+1;
else if(move_cursor)
if(move_dir==1'b1 && mem_monitor2[7:0]==ceo)
output_device_next = output_device+1;
else if(move_dir==1'b0 && mem_monitor1[7:0]==ceo)
output_device_next = output_device+1;
end
*/
endmodule
module Controller_module (
input controller_change_mode //sync var
);
reg controller_mode=0;
parameter hat = 4'b0000,
add = 4'b0001,
sub = 4'b0010,
mol = 4'b0011,
mor = 4'b0100,
inp = 4'b0101,
oup = 4'b0110,
lol = 4'b0111,
lor = 4'b1000,
ceo = 4'b1001,
zer = 4'b1010,
pas = 4'b1011;
//declare: working_clock
//tape
Tape_module tape(
.working_clock(working_clock),
.tape_new_symbol(keypad_symbol),
.tape_set_symbol(tape_set_symbol),
.tape_move_dir(tape_move_dir),
.tape_move(tape_move),
.tape_symbol(tape_symbol),
.reset(tape_reset),
.roll_back(tape_roll_back),
.tape_delete(tape_delete)
);
wire tape_symbol;
//reg [3:0]tape_new_symbol;
reg tape_move_dir;
reg tape_set_symbol, tape_set_symbol_next;
reg tape_move, tape_move_next;
reg tape_roll_back, tape_roll_back_next;
reg tape_delete, tape_delete_next;
//memory
Memory_module memory(
.working_clock(working_clock),
.ptr_value(ptr_value),
.ptr_new_value(ptr_new_value),
.ptr_move_dir(ptr_move_dir),
.ptr_set_value(ptr_set_value),
.ptr_move(ptr_move),
.reset(mem_reset),
.roll_back(ptr_roll_back),
.mem_monitor2(mem_monitor2),
);
wire [7:0]ptr_value;
wire [13:0]mem_monitor2;
reg [7:0]ptr_new_value;
reg ptr_move_dir;
reg ptr_set_value, ptr_set_value_next;
reg ptr_move, ptr_move_next;
reg ptr_roll_back, ptr_roll_back_next;
//keypaddriver,facilities are not assign yet
KeypadDriver_module keypad_driver(
.reset(keypad_reset),
.working_clock(working_clock),
.to_mode(controller_mode),
.change_mode(keypad_change_mode),
.cmd_mode(cmd_mode),
.symbol(keypad_symbol),
.available(keypad_available),
.explicit_pull_key(keypad_pull_key) //as signal
);
wire cmd_mode;
wire keypad_symbol;
wire keypad_available;
//reg keypad_to_mode;
reg keypad_change_mode, keypad_change_mode_next;
//LED ,facilities are not assign yet
reg [7:0]led_char;
reg led_update, led_update_next;
//14seg ,facilities are not assign yet
reg [7:0]seg_char;
reg seg_update, seg_update_next;
//Console ,facilities are not assign yet
Console_module console(
.console_reset(console_reset),
.console_to_mode(controller_mode),
.console_change_mode(console_change_mode),
.console_please_wait(console_please_wait),
.console_mem_monitor2(mem_monitor2),
.console_symbol_to_insert(keypad_symbol),
.console_insert(console_insert),
.console_delete(console_delete),
.console_cursor_dir(console_cursor_dir | keypad_cursor_move_dir),
.console_move_cursor(console_move_cursor)
);
//reg console_to_mode;
reg console_cursor_dir;
reg console_change_mode, console_change_mode_next;
reg console_please_wait, console_please_wait_next;
reg console_insert, console_insert_next;
reg console_delete, console_delete_next;
reg console_move_cursor, console_move_cursor_next;
//wire console_reset
//wire tape_reset, aux_tape_reset,aux_tape_reset_next;
//wire mem_reset, aux_mem_reset,aux_mem_reset_next;
//wire keypad_pull_key, aux_keypad_pull_key,aux_keypad_pull_key_next;
//wire keypad_reset, aux_keypad_reset,aux_keypad_reset_next;
//wire led_reset, aux_led_reset,aux_led_reset_next;
//wire seg_reset, aux_seg_reset,aux_seg_reset_next;
/*SMDL
(state-machine
(clock "working_clock")
(init-state init)
(state
(default
(sync-var
("tape_set_symbol" "1'b0")
("tape_move" "1'b0")
("tape_roll_back" "1'b0")
("tape_delete" "1'b0")
("ptr_set_value" "1'b0")
("ptr_move" "1'b0")
("ptr_roll_back" "1'b0")
("keypad_change_mode" "1'b0")
("led_update" "1'b0")
("seg_update" "1'b0")
("console_change_mode" "1'b0")
("console_please_wait" "1'b0")
("console_insert" "1'b0")
("console_delete" "1'b0")
("console_move_cursor" "1'b0")
)
(reg
("tape_move_dir" "1'b0")
("tape_new_symbol" "3'b000")
("ptr_move_dir" "1'b0")
("ptr_new_value" "8'd0")
("console_cursor_dir" "1'b0")
("controller_mode" "1'b0")
))
(init
(sync-var
("keypad_change_mode" "1'b1")
("console_change_mode" "1'b1"))
(reg
("keypad_to_mode" "1'b0")
("console_to_mode" "1'b0")))
(edit)
(edit_insert_symbol
(sync-var
("console_insert" "1'b1")
("tape_set_symbol" "1'b1")))
(edit_delete_symbol
(sync-var
("console_delete" "1'b1")
("tape_delete" "1'b1")))
(trans-func
((init)
(edit "tape_reset"
"mem_reset"
"led_reset"
"seg_reset"))
;edit transfunc
((edit (and
("keypad_available" "==" "1'b1")
("cmd_mode" "==" "1'd0")))
(edit_insert_symbol))
((edit (and
("keypad_available" "==" "1'b1")
("cmd_mode" "==" "1'd1")))
(edit_delete_symbol))
((edit ("controller_change_mode" "==" "1'b1"))
(edit_to_exe))
((edit) (edit))
((edit_insert_symbol)
(edit_move_tapeR "keypad_pull_key"))
((edit_delete_symbol)
(edit_move_tapeL "keypad_pull_key"))
((edit_move_tapeR) (edit))
((edit_move_tapeL) (edit))
;gray area
((edit_to_exe) (exe))
((exe_to_edit) (edit))
;exe trans funcs
*/
module KeypadDriver_module(
input reset,
input keypad_clock,
input working_clock,
input to_mode, //0 for edit, 1 for exe
input change_mode,
//edit mode
output reg cmd_mode, //0 for symbol 1 for delete
output reg [3:0]symbol,//cmd_mode=0
//output reg cursor_move_dir, //cmd_mode=1
//output reg backspace, //cmd_mode=2
//execute mode
//use "symbol" port
output reg available = 1'b0,
input explicit_pull_key
);
reg mode,mode_next = 0; //0 for edit, 1 for exe
reg cmd_mode_next = 0;
reg [3:0]symbol_next;
wire pull_key;
wire auto_pull_key;
reg aux_auto_pull_key,aux_auto_pull_key_next;
assign auto_pull_key = aux_auto_pull_key_next & working_clock;
assign pull_key = explicit_pull_key | auto_pull_key;
keypad kp( .key_available(key_available),
.key(key),
.pull_key(pull_key));
wire key_available;
reg available_next = 1'b0;
wire [3:0]key;
parameter INIT = 2'b00,
EDIT = 2'b01,
EXE = 2'b10;
parameter hat = 4'b0000,
add = 4'b0001,
sub = 4'b0010,
mol = 4'b0011,
mor = 4'b0100,
inp = 4'b0101,
oup = 4'b0110,
lol = 4'b0111,
lor = 4'b1000,
ceo = 4'b1001,
zer = 4'b1010,
pas = 4'b1011;
always@(posedge working_clock,posedge reset) begin
if(reset) begin
_state <= INIT;
available <= 1'b0;
end else begin
_state <= _state_next;
mode <= mode_next;
available <= available_next;
cmd_mode <= cmd_mode_next;
symbol <= symbol_next;
cursor_move_dir <= cursor_move_dir_next;
backspace <= backspace_next;
clear_memory <= clear_memory_next;
end
end
always@(*) begin
mode_next = mode;
_state_next = INIT;
cmd_mode_next = 0;
symbol_next = symbol;
available_next = 1'b0;
aux_auto_pull_key_next = 1'b0;
case(_state)
INIT: begin
if(change_mode) begin
if(to_mode==1'b1)
_state_next = EXE;
else
_state_next = EDIT;
end else
_state_next = INIT;
end
EDIT: begin
if(key_available) begin
available_next = 1'b1;
case (key)
4'h0: begin
cmd_mode_next = 1'd0;
symbol_next = zer;
end
4'h1: begin
cmd_mode_next = 1'd0;
symbol_next = inp;
end
4'h2: begin
cmd_mode_next = 1'd0;
symbol_next = oup;
end
4'h3: begin
cmd_mode_next = 1'd0;
symbol_next = pas;
end
4'h4: begin
cmd_mode_next = 1'd0;
symbol_next = mol;
end
4'h5: begin
cmd_mode_next = 1'd0;
symbol_next = sub;
end
4'h6: begin
cmd_mode_next = 1'd0;
symbol_next = lol;
end
4'h7: begin
cmd_mode_next = 1'd0;
symbol_next = mor;
end
4'h8: begin
cmd_mode_next = 1'd0;
symbol_next = add;
end
4'h9: begin
cmd_mode_next = 1'd0;
symbol_next = lor;
end
4'ha: begin
cmd_mode_next = 1'd0;
symbol_next = ceo;
end
4'hb: begin
cmd_mode_next = 1'd0;
end
default: begin
available_next = 1'b0;
aux_auto_pull_key_next = 1'b1;
end
endcase
end
if(change_mode && to_mode==1'b1) begin
_state_next = EXE;
end else begin
_state_next = EDIT;
end
end
EXE: begin
if(key_available) begin
available_next = 1'b1;
symbol_next = key;
end
if(change_mode && to_mode==1'b0) begin
_state_next = EDIT;
end else begin
_state_next = EXE;
end
end
default: begin
_state_next = INIT;
end
endcase
end
endmodule
module Memory_module (
input working_clock,
output [7:0]ptr_value,
input [7:0]ptr_new_value,
input ptr_move_dir,
input ptr_set_value, //signal
input ptr_move, //signal
input reset,
input roll_back,
//output [13:0]mem_monitor1,//{mem_addr,mem_content}
output [13:0]mem_monitor2,
//output [13:0]mem_monitor3
output reg available = 1'b0
);
reg available_next = 1'b0;
reg [0:511]memory,memory_next; //8bit * 128
//reg [8:0]ptr = 9'd0;
//reg [8:0]ptr_next;
assign ptr_value = memory[0:7];
reg [5:0]address = 6'd0;
reg [5:0]address_next;
reg [5:0]mov_counter,mov_counter_next;
//assign mem_monitor1 = {address-6'd1,memory[508:511]};
assign mem_monitor2 = {address,ptr_value};
//assign mem_monitor3 = {address+6'd1,memory[8:15]};
parameter INIT = 2'd0,
WAIT = 2'd1,
MOVL = 2'd2,
MOVR = 2'd3;
reg [1:0]_state = INIT;
reg [1:0]_state_next = INIT;
always@(posedge working_clock,posedge reset) begin
if(reset) begin
_state <= INIT;
available <= 1'b0;
address <= 6'd0;
mov_counter <= 6'd0;
end else begin
_state <= _state_next;
memory <= memory_next;
//ptr <= ptr_next;
address <= address_next;
available <= available_next;
mov_counter <= mov_counter_next;
end
end
always@(*) begin
//ptr_next = ptr;
memory_next = memory;
address_next = address;
available_next = 1'b0;
mov_counter_next = mov_counter;
case(_state)
INIT: begin
memory_next = 512'd0;
_state_next = WAIT;
//ptr_next = 9'd0;
address_next = 6'd0;
available_next = 1'b1;
mov_counter_next = 6'b0;
end
WAIT: begin
if(ptr_set_value) begin
memory_next = {ptr_new_value,memory[8:511]};
_state_next = WAIT;
available_next = 1'b1;
end else if(ptr_move &&
ptr_move_dir==1'b1 &&
address < 6'd63) begin
mov_counter_next = 6'd1;
_state_next = MOVR;
end else if(ptr_move &&
ptr_move_dir==1'b0 &&
address > 6'd0) begin
mov_counter_next = 6'd1;
_state_next = MOVL;
end else if(roll_back && address>6'd0) begin
_state_next = MOVL;
mov_counter_next = address;
end else begin
_state_next = WAIT;
available_next = 1'b1;
end
end
MOVL: begin
memory_next = {memory[504:511],memory[0:503]};
if(mov_counter == 6'd1) begin
mov_counter_next = 6'd0;
_state_next = WAIT;
available_next = 1'b1;
address_next = address - 1;
end else begin
mov_counter_next = mov_counter - 1;
address_next = address - 1;
_state_next = MOVL;
end
end
MOVR: begin
memory_next = {memory[8:511],memory[0:7]};
if(mov_counter == 6'd1) begin
mov_counter_next = 6'd0;
_state_next = WAIT;
available_next = 1'b1;
address_next = address + 1;
end else begin
mov_counter_next = mov_counter - 1;
address_next = address + 1;
_state_next = MOVR;
end
end
default:
_state_next = INIT;
endcase
end
endmodule
module Tape_module (
input working_clock,
input [3:0]tape_new_symbol,
input tape_set_symbol,
input tape_move_dir,
input tape_move,
output [3:0]tape_symbol,
input reset,
input roll_back,
input tape_delete,
output reg available = 1'b0
);
reg available_next = 1'b0;
reg [0:511]tape,tape_next = 512'd0; //128*4bit symbols
//reg [8:0]tape_ptr=0;
//reg [8:0]tape_ptr_next;
assign tape_symbol = tape[0:3];
reg [6:0]counter,counter_next = 7'd0;
reg [6:0]mov_counter,mov_counter_next;
parameter hat = 4'b0000,
add = 4'b0001,
sub = 4'b0010,
mol = 4'b0011,
mor = 4'b0100,
inp = 4'b0101,
oup = 4'b0110,
lol = 4'b0111,
lor = 4'b1000,
ceo = 4'b1001,
zer = 4'b1010,
pas = 4'b1011;
parameter INIT = 2'd0,
WAIT = 2'd1,
MOVL = 2'd2,
MOVR = 2'd3;
reg [1:0]_state = INIT;
reg [1:0]_state_next = INIT;
always@(posedge working_clock,posedge reset) begin
if(reset) begin
_state <= INIT;
available <= 1'b0;
counter <= 7'd0;
mov_counter <= 7'd0;
end else begin
_state <= _state_next;
tape <= tape_next;
//tape_ptr <= tape_ptr_next;
available <= available_next;
counter <= counter_next;
mov_counter <= mov_counter_next;
end
end
always@(*) begin
//tape_ptr_next = tape_ptr;
tape_next = tape;
available_next = 1'b0;
mov_counter_next = mov_counter;
case(_state)
INIT: begin
tape_next = 512'd0;
//tape_ptr_next = 9'd0;
_state_next = WAIT;
available_next = 1'b1;
counter_next = 7'd0;
mov_counter_next = 7'd0;
end
WAIT: begin
if(tape_set_symbol) begin
tape_next = {tape_new_symbol,tape[4:511]};
_state_next = WAIT;
available_next = 1'b1;
end else if(tape_move &&
tape_move_dir==1'b1 &&
counter<7'd127) begin
mov_counter_next = 7'd1;
_state_next = MOVR;
end else if(tape_move &&
tape_move_dir==1'b0 &&
counter>7'd0) begin
mov_counter_next = 7'd1;
_state_next = MOVL;
end else if(roll_back && counter>7'd0) begin
_state_next = MOVL;
mov_counter_next = counter;
end else if(tape_delete) begin
tape_next = {hat,tape[4:511]};
_state_next = WAIT;
available_next = 1'b1;
end else begin
_state_next = WAIT;
available_next = 1'b1;
end
end
MOVL: begin
tape_next = {tape[508:511],tape[0:507]};
if(mov_counter == 7'd1) begin
mov_counter_next = 7'd0;
_state_next = WAIT;
available_next = 1'b1;
counter_next = counter - 1;
end else begin
mov_counter_next = mov_counter - 1;
counter_next = counter - 1;
_state_next = MOVL;
end
end
MOVR: begin
tape_next = {tape[4:511],tape[0:3]};
if(mov_counter == 7'd1) begin
mov_counter_next = 7'd0;
_state_next = WAIT;
available_next = 1'b1;
counter_next = counter + 1;
end else begin
mov_counter_next = mov_counter - 1;
counter_next = counter + 1;
_state_next = MOVR;
end
end
default:
_state_next = INIT;
endcase
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment