This is a very simple microprocesor written in Verilog:
The alu.v:
module alu( a, b, c, F2, F1, F0);
input [7:0] a;
input [7:0] b;
input F2,F1,F0;
output reg[7:0] c;
always@(*)
begin
if(F2==0 && F1==0 && F0==0)
c=a;
if(F2==0 && F1==0 && F0==1)
c=b;
if(F2==0 && F1==1 && F0==0)
c=a+1;
if(F2==0 && F1==1 && F0==1)
c=b+1;
if(F2==1 && F1==0 && F0==0)
c=a+b;
if(F2==1 && F1==0 && F0==1)
c=a-b;
if(F2==1 && F1==1 && F0==0)
c=(a & b);
if(F2==1 && F1==1 && F0==1)
c=(a | b);
end
endmodule
module mux( b,mbr, pc,outmux,pins,F1,F0);
input [7:0] b,mbr,pc,pins;
input F1,F0;
output reg [7:0] outmux;
always@(*)
begin
if( F1==0 && F0==0)
outmux=b;
if( F1==0 && F0==1)
outmux=mbr;
if( F1==1 && F0==0)
outmux=pc;
if(F1==1 && F0==1)
outmux=pins;
end
endmodule
module mux2( mbr, address,JMPC,out_mux2);
input clk;
input [4:0] mbr;
input [4:0] address;
input JMPC;
output reg [4:0] out_mux2;
always@(*)
begin
if( JMPC==0)
out_mux2=address;
if( JMPC==1 )
out_mux2=mbr;
end
endmodule
module ROM(romaddr,clk,romdout);
parameter size=2;
input clk;
input [4:0] romaddr;
output reg [15:0] romdout;
always @(*)
case (romaddr)
0 : romdout = 16'b0000100000000100;//804 Fetch MBR
1 : romdout = 16'b0001000111000000;//11C0 PC=PC+1
2 : romdout = 16'b0001100111001000;//19C8 Store PC
3 : romdout = 16'b0000010000000000;//0400 Goto MBR
5 : romdout = 16'b0011000000000100;//3004 LOAD A,#0 // Load MBR with MEM
6 : romdout = 16'b0000000010100001;//00A1 LOAD A
7 : romdout = 16'b0000000100100001;//40A4 INC A // Load MBRA with MEM
8 : romdout = 16'b000000100100001;//0020 INC A
default : romdout = 16'b0000000000000000;//0020 NOP
endcase
endmodule
module RAM(ramaddr,clk,ramdout);
parameter size=2;
input clk;
input [7:0] ramaddr;
output reg [7:0] ramdout;
always @(*)
case (ramaddr)
0 : ramdout = 16'b00000000;// NOP
1 : ramdout = 16'b00000000;// NOP
2 : ramdout = 16'b00000101;//05 Load A,#A6
3 : ramdout = 16'b10100110;//#A6
4 : ramdout = 16'b00000111;//07 INC A
5 : ramdout = 16'b00000111;//07 INC A
default : ramdout = 16'b00000000;//00
endcase
endmodule
module main;
reg reset=0;
reg[7:0] A;
reg[7:0] B;
reg[4:0] MPC;
reg[7:0] pins;
reg[7:0] MBR;
reg[7:0] OUT,pc;
reg[15:0] MIR;
wire[15:0] bus_MIR;
wire [7:0]bus_pc,bus_out_b,bus_pins;
wire [4:0]muxout;
wire [7:0]bus_data;
always @(posedge MIR[3])
pc=C;
always @(posedge MIR[4])
OUT=C;
always @( MIR[0])
A=C;
always @(posedge MIR[1])
B=C;
always @(posedge clk)
MPC=muxout;
always @(negedge clk )
if(reset==0)
MIR=bus_MIR;
always @(posedge MIR[2])
MBR=bus_data;
initial
begin
$dumpfile("main.vcd");
$dumpvars(0,main);
reset=1;
MPC=0;
pc<=0;
MBR<=0;
A<=0;
B<=0;
pins=10;
#2;
reset=0;
#3;
#100;
$finish;
end
reg clk=0;
wire [7:0] C;
mux mux( B,MBR, pc,bus_out_b,bus_pins,MIR[6],MIR[5]);
mux2 MUX2( MBR[4:0],MIR[15:11],MIR[10],muxout);
alu ALU(A,bus_out_b,C,MIR[9],MIR[8],MIR[7]);
ROM rom (MPC,clk,bus_MIR);
RAM ram (pc,clk,bus_data);
always #1 clk = !clk;
endmodule
The command to compile:
iverilog -o dsn alu.v
vvp dsn
gtkwave main.vcd &
It is based on this document http://db.grinnell.edu/sigcse/sigcse2013/Program/viewAcceptedProposal.pdf?sessionType=paper&sessionNumber=39. Only the logical diagram is given so I did the verilog part.
I put additional microcode and registers to enhance the functionality.It works in a Altera Stratix kit.
miércoles, 30 de octubre de 2013
Simple file loading and display in assembler.
This program let's you load a file and display it in the STDOUT
#nasm -f elf tiny.asm
#gcc -Wall -s -nostdlib tiny.o
;tiny.asm
BITS 32
GLOBAL _start
SECTION .text
_start:
pop ebx ;argc
pop ebx ;argv[0]
pop ebx ;the file name
mov eax,5 ;the syscall number for open()
;the name is in ebx
mov ecx,0 ;O_RDONLY as in fcntl
int 0x80
test eax,eax ;it is not NULL
jns file_function
mov ebx,eax ;any error goes to ebx
mov eax,1 ;exit syscall
int 0x80
file_function:
mov ebx,eax ;file descriptor
mov eax,3 ;sys read
mov ecx,buf ;*buf
mov edx,bufsize ;*bufsize
int 0x80
write:
mov edx,eax
mov eax,4
mov ebx,1
int 0x80
exit: ;exit(0)
mov eax,1
mov ebx,0
int 0x80
section .data
bufsize dw 1024
section .bss
buf resb 1024
check this site http://leto.net/writing/nasm.php
#nasm -f elf tiny.asm
#gcc -Wall -s -nostdlib tiny.o
It uses some linux calls to load the file.
This is intended to be a small description on how the .text, .data and .bss sections work. The code is in the .text section of the ELF file format while the other sections are basically the data zones.
;tiny.asm
BITS 32
GLOBAL _start
SECTION .text
_start:
pop ebx ;argc
pop ebx ;argv[0]
pop ebx ;the file name
mov eax,5 ;the syscall number for open()
;the name is in ebx
mov ecx,0 ;O_RDONLY as in fcntl
int 0x80
test eax,eax ;it is not NULL
jns file_function
mov ebx,eax ;any error goes to ebx
mov eax,1 ;exit syscall
int 0x80
file_function:
mov ebx,eax ;file descriptor
mov eax,3 ;sys read
mov ecx,buf ;*buf
mov edx,bufsize ;*bufsize
int 0x80
write:
mov edx,eax
mov eax,4
mov ebx,1
int 0x80
exit: ;exit(0)
mov eax,1
mov ebx,0
int 0x80
section .data
bufsize dw 1024
section .bss
buf resb 1024
check this site http://leto.net/writing/nasm.php
Suscribirse a:
Entradas (Atom)