mirror of
https://github.com/verilator/verilator.git
synced 2025-01-10 08:37:35 +00:00
230 lines
5.6 KiB
Systemverilog
230 lines
5.6 KiB
Systemverilog
// DESCRIPTION: Verilator: Large test for SystemVerilog
|
|
|
|
// This file ONLY is placed into the Public Domain, for any use,
|
|
// without warranty, 2012.
|
|
|
|
// Contributed by M W Lund, Atmel Corporation.
|
|
|
|
module cpu
|
|
#( parameter
|
|
// ...
|
|
ID = 1 ) // Not used!
|
|
(
|
|
// ***************************************************************************
|
|
// Module Interface (interfaces, outputs, and inputs)
|
|
// ***************************************************************************
|
|
|
|
// **** Interfaces ****
|
|
genbus_if.master dbus,
|
|
|
|
|
|
// **** Outputs ****
|
|
// N/A
|
|
|
|
|
|
// **** Inputs ****
|
|
input logic clk,
|
|
input logic rst
|
|
);
|
|
|
|
// ***************************************************************************
|
|
// Regs and Wires
|
|
// ***************************************************************************
|
|
|
|
// **** Program Memory ****
|
|
logic [15:0] rom_out;
|
|
|
|
|
|
// **** Register File (RF) ****
|
|
logic [7:0] rf[0:15];
|
|
|
|
|
|
// **** Fetch Stage ****
|
|
logic [7:0] pc; // PC -> Program counter.
|
|
logic [15:0] ir; // IR -> Instruction Register.
|
|
|
|
|
|
// **** Decode ****
|
|
logic [3:0] idec_rd;
|
|
logic idec_rd_we;
|
|
logic [7:0] idec_rd_data;
|
|
logic [3:0] idec_rs;
|
|
|
|
logic [7:0] idec_nextpc; // New PC if change of program flow.
|
|
|
|
logic idec_coff; // Indicates a change of program flow.
|
|
|
|
logic [7:0] idec_mem_adr;
|
|
logic idec_mem_re;
|
|
logic idec_mem_we;
|
|
|
|
|
|
// **** Memory ****
|
|
logic [7:0] mem_data; // Data from peripheral.
|
|
logic mem_ws; // Waitstate.
|
|
|
|
|
|
// ***************************************************************************
|
|
// Program Memory (ROM) Interface
|
|
// ***************************************************************************
|
|
|
|
always_comb
|
|
begin: ROM
|
|
// - Local Variables -
|
|
integer i;
|
|
reg [15:0] irom [0:255];
|
|
|
|
// - Set default -
|
|
for ( i = 0; i < 256; i++ )
|
|
begin
|
|
if ( i < $size(rom) )
|
|
irom[i] = rom[i];
|
|
else
|
|
irom[i] = 16'h0000;
|
|
end
|
|
|
|
rom_out = irom[pc[7:0]];
|
|
end
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
// Register File (RF)
|
|
// ***************************************************************************
|
|
|
|
always_ff @( posedge clk )
|
|
begin: RegFile
|
|
// - Local Variables -
|
|
integer i;
|
|
|
|
// - Register File -
|
|
for ( i = 0; i < 16; i++ )
|
|
begin
|
|
if ( rst )
|
|
rf[i][7:0] <= 8'h00;
|
|
else if ( idec_rd_we & (idec_rd == i[3:0]) )
|
|
rf[i] <= idec_rd_data;
|
|
end
|
|
end
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
// Fetch Stage
|
|
// ***************************************************************************
|
|
|
|
// **** Program Counter (PC) / Instruction Register (IR) ****
|
|
always_ff @( posedge clk )
|
|
begin
|
|
if ( rst )
|
|
begin
|
|
pc <= 8'h00;
|
|
ir <= 16'h0000;
|
|
end
|
|
else //if ( ~mem_ws )
|
|
begin
|
|
if ( ~idec_coff )
|
|
begin
|
|
pc <= pc + 1;
|
|
ir <= rom_out; // Fetch Instruction.
|
|
end
|
|
else
|
|
begin
|
|
pc <= idec_nextpc;
|
|
ir <= 16'h0000; // Insert no operation (NOP).
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
// Decode/Execute Stage
|
|
// ***************************************************************************
|
|
|
|
always_comb
|
|
begin
|
|
// - Defaults -
|
|
idec_rd = 4'h0;
|
|
idec_rd_we = 1'b0;
|
|
idec_rd_data = 8'h00;
|
|
idec_rs = 4'h0;
|
|
|
|
idec_nextpc = 8'h00;
|
|
idec_coff = 1'b0;
|
|
|
|
idec_mem_adr = 8'h00;
|
|
idec_mem_re = 1'b0;
|
|
idec_mem_we = 1'b0;
|
|
|
|
casez ( ir )
|
|
16'h0000:; // NOP (<=> Default)
|
|
|
|
16'h1???: // JMP imm
|
|
begin
|
|
idec_nextpc = ir[7:0];
|
|
idec_coff = 1'b1;
|
|
end
|
|
|
|
16'h4???: // LDI rd, imm
|
|
begin
|
|
idec_rd = ir[8+:4];
|
|
idec_rd_we = 1'b1;
|
|
idec_rd_data = ir[0+:8];
|
|
end
|
|
|
|
16'h8???:
|
|
begin // STS imm, rs
|
|
idec_mem_adr = ir[0+:8];
|
|
idec_mem_we = 1'b1;
|
|
idec_rs = ir[8+:4];
|
|
end
|
|
|
|
16'h9???:
|
|
begin // LDS rd, imm
|
|
idec_mem_adr = ir[0+:8];
|
|
idec_mem_we = 1'b1;
|
|
idec_rd = ir[8+:4];
|
|
idec_rd_we = 1'b1;
|
|
idec_rd_data = mem_data[0+:8];
|
|
end
|
|
endcase
|
|
end
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
// Memory Access ("Stage")
|
|
// ***************************************************************************
|
|
|
|
// **** Connect to "dbus" ****
|
|
always_comb
|
|
begin: Conntect
|
|
reg [15:0] sdata16;
|
|
|
|
dbus.mConnect
|
|
( ID, // ID
|
|
sdata16, // sdata
|
|
mem_ws, // ws
|
|
{2{rf[idec_rs]}}, // mdata
|
|
// adr
|
|
{8'h00, idec_mem_adr[7:1], 1'b0},
|
|
// we
|
|
{idec_mem_adr[0],~idec_mem_adr[0]} & {2{idec_mem_we}},
|
|
// re
|
|
{idec_mem_adr[0],~idec_mem_adr[0]} & {2{idec_mem_re}}
|
|
);
|
|
|
|
// - Connect 16-bit databus to 8-bit CPU -
|
|
mem_data = ( idec_mem_adr[0] ) ? sdata16[15:8] : sdata16[7:0];
|
|
end
|
|
|
|
|
|
mPreAdrDecode_resp busproperty;
|
|
always_comb
|
|
begin: PreAdrDecode
|
|
busproperty = dbus.mPreAdrDecode( 0, idec_mem_adr );
|
|
end
|
|
|
|
endmodule // cpu
|